From 7c86336016b8c3066faee5acf73f4659c3926179 Mon Sep 17 00:00:00 2001
From: Your Name <you@example.com>
Date: Sun, 19 Jan 2025 17:27:07 +0100
Subject: [PATCH] add tests

---
 .gitlab-ci.yml                   | 14 ++++--
 run_pm_dmo_NFW_fixed_timestep.md | 85 +-------------------------------
 test_dmo_NFW_fixed_timestep.py   | 82 ++++++++++++++++++++++++++++++
 test_editable.bash               |  5 +-
 test_install_pm.bash             |  1 +
 test_pip_all.bash                |  2 +-
 6 files changed, 98 insertions(+), 91 deletions(-)
 create mode 100644 test_dmo_NFW_fixed_timestep.py
 create mode 100644 test_install_pm.bash

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 259af50..20dc724 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -10,13 +10,17 @@ before_script:
     ENV HW_FLAGS="-Wl,--no-as-needed"
     ENV MPIRUN='mpirun --allow-run-as-root -n 2'
     ENV OMP_NUM_THREADS=2
-    ARG USER
-    ARG PASS
-    RUN git config --global url."https://\${USER}:\${PASS}@www.ict.inaf.it/gitlab".insteadOf ssh://git@git.ia2.inaf.it
+    RUN apt-get install -y libgsl-dev libgsl27
+    RUN pip install matplotlib
+    RUN apt-get install -y libfftw3-dev libfftw3-mpi-dev
+    RUN apt-get install -y wget
+    RUN pip install Jinja2 numpy  PyYAML libclang numba 
+    RUN git config --global url."https://${CI_REGISTRY_USER}:${CI_JOB_TOKEN}@www.ict.inaf.it/gitlab".insteadOf ssh://git@git.ia2.inaf.it
     WORKDIR /app
     COPY . /app
     EOF
   
-testing:
+install:
   script:
-    - docker run hwmd bash -c './test_install_octree.bash; ./test_checkup.bash; ./test_pip_all.bash; ./test_editable.bash; ./test_bulk.bash' 
\ No newline at end of file
+    - docker run hwmd bash -c 'set -xev;  . test_install_octree.bash && . test_checkup.bash && . test_pip_all.bash && . test_editable.bash && . test_bulk.bash'
+    - docker run hwmd bash -c 'set -xev; . test_install_pm.bash && python3 test_dmo_NFW_fixed_timestep.py'
diff --git a/run_pm_dmo_NFW_fixed_timestep.md b/run_pm_dmo_NFW_fixed_timestep.md
index 9365f0b..da7cc74 100644
--- a/run_pm_dmo_NFW_fixed_timestep.md
+++ b/run_pm_dmo_NFW_fixed_timestep.md
@@ -8,92 +8,11 @@ Here is a first benefit of a modular code: since in `hotwheels `PM is a self-con
 Install the PM module (will install core,IO, and timestep as dependencies):
 
 ```bash
-pip install 'howtheels_PM[tested] @ git+ssh://git@git.ia2.inaf.it/hotwheels/PM.git@v0.0.0alpha'
+::include{file=test_install_pm.bash}
 ```
 
 And you can run this code:
 
 ```python
-import numpy as np, os, matplotlib as plt
-from hotwheels.utils import *
-from hotwheels.wrap import *
-from hotwheels.soas import *
-from hotwheels.PM import *
-from hotwheels.integrate import *
-from hotwheels.io import *
-
-#
-# Step 1: Configure components
-# This stage configures components without allocating resources.
-# Configurations are passed to constructors to compile the underlying C libraries.
-#
-
-mpi = MPI().init() # Initialize MPI
-mym = MyMalloc(alloc_bytes=int(2e9)) # Configure memory allocator with 2GB
-p = SoA(maxpart=int(1e5), mem=mym) # Configure P to hold 1e5 particles
-soas = SoAs(p) # Add P to a multi-type SoA container
-# Set up a fixed time-step integrator from 0 to 1 Gyr
-# Conversion factor for Gyr to internal units
-gyr_to_cu = 3.086e+16 / (1e9 * 3600 * 24 * 365)
-ts = FixedTimeStep(
-    soas,
-    G=43007.1,  # Gravitational constant in specific units
-    t_from=0.,
-    t_to=1. * gyr_to_cu,
-    MPI=mpi
-)
-# Initialize a NFW profile with scale radius `rs=100` and density `rho0=1e-6`
-ic = NFWIC(r_s=100., rho_0=1e-6, r_max_f=10.)
-# Configure a refined PM grid with 7 stacked high-resolution regions
-pm = SuperHiResPM( #wrapper to the PM C library
-    soas=soas,
-    mem=mym,
-    TS=ts, #will use it to attach gravkick callback
-    MPI=mpi,
-    pmgrid=128,
-    grids=8, # number of grids to instantiate
-    dt_displacement_factor=0.25 #factor for DtDisplacement
-)
-build = make.Build('./', mpi, pm, ts, mym, *soas.values()) # Compile all modules in the current directory
-headers = OnTheFly(build.build_name, *build.components, generate_user_c=True) # Generate SoA headers
-
-if mpi.rank == 0:  # Master rank handles compilation
-    headers.write()
-    build.compile()
-
-#
-# Step 2: Allocate resources
-#
-
-with (
-    Panic(Build=build) as panic,  # Attach panic handler
-    Timer(Build=build) as timer,  # Attach timer handler
-    build.enter(debug=mpi.rank == 0),  # Parse compiled objects
-    mpi.enter(pm),  # Initialize MPI in the PM module
-    mym.enter(*build.components),  # Allocate 2GB memory
-    p,  # Allocate particle data structure in MyMalloc
-    ic.enter(p, mpi.ranks, p.get_maxpart(), ts.G),  # Sample NFW profile
-    pm,  # Initialize PM and compute first accelerations
-    ts  # Compute DriftTables if needed
-):
-
-    #
-    # Step 3: Main simulation loop
-    #
-    while ts.time < ts.time_end:
-        ts.find_timesteps()  # Determine timesteps
-        ts.do_first_halfstep_kick()  # First kick (includes drift/kick callbacks)
-        ts.drift()  # Update particle positions
-        pm.compute_accelerations()  # Recompute accelerations
-        ts.do_second_halfstep_kick()  # Second kick
-
-        # Occasionally, generate plots on the master rank
-        if mpi.rank == 0 and ts.steps % 10 == 0:
-            fig, ax = plt.subplots(1)
-            ax.hist2d(p['pos'][:, 0], p['pos'][:, 1], bins=128)
-            ax.set_aspect('equal')
-            fig.savefig(f'snap{ts.steps}_rank{mpi.rank}.png', bbox_inches='tight', dpi=200)
-            plt.close(fig)
-
-print('Simulation finished')
+::include{file=test_dmo_NFW_fixed_timestep.py}
 ```
\ No newline at end of file
diff --git a/test_dmo_NFW_fixed_timestep.py b/test_dmo_NFW_fixed_timestep.py
new file mode 100644
index 0000000..1a87a19
--- /dev/null
+++ b/test_dmo_NFW_fixed_timestep.py
@@ -0,0 +1,82 @@
+import numpy as np, os, matplotlib as plt
+from hotwheels_core.utils import *
+from hotwheels_core.wrap import *
+from hotwheels_core.soas import *
+from hotwheels_PM import *
+from hotwheels_integrate import *
+from hotwheels_io import *
+
+#
+# Step 1: Configure components
+# This stage configures components without allocating resources.
+# Configurations are passed to constructors to compile the underlying C libraries.
+#
+
+mpi = MPI().init() # Initialize MPI
+mym = MyMalloc(alloc_bytes=int(2e9)) # Configure memory allocator with 2GB
+p = SoA(maxpart=int(1e5), mem=mym) # Configure P to hold 1e5 particles
+soas = SoAs(p) # Add P to a multi-type SoA container
+# Set up a fixed time-step integrator from 0 to 1 Gyr
+# Conversion factor for Gyr to internal units
+gyr_to_cu = 3.086e+16 / (1e9 * 3600 * 24 * 365)
+ts = FixedTimeStep(
+    soas,
+    G=43007.1,  # Gravitational constant in specific units
+    t_from=0.,
+    t_to=1. * gyr_to_cu,
+    MPI=mpi
+)
+# Initialize a NFW profile with scale radius `rs=100` and density `rho0=1e-6`
+ic = NFWIC(r_s=100., rho_0=1e-6, r_max_f=10.)
+# Configure a refined PM grid with 7 stacked high-resolution regions
+pm = SuperHiResPM( #wrapper to the PM C library
+    soas=soas,
+    mem=mym,
+    TS=ts, #will use it to attach gravkick callback
+    MPI=mpi,
+    pmgrid=128,
+    grids=8, # number of grids to instantiate
+    dt_displacement_factor=0.25 #factor for DtDisplacement
+)
+build = make.Build('./', mpi, pm, ts, mym, *soas.values()) # Compile all modules in the current directory
+headers = OnTheFly(build.build_name, *build.components, generate_user_c=True) # Generate SoA headers
+
+if mpi.rank == 0:  # Master rank handles compilation
+    headers.write()
+    build.compile()
+
+#
+# Step 2: Allocate resources
+#
+
+with (
+    Panic(Build=build) as panic,  # Attach panic handler
+    Timer(Build=build) as timer,  # Attach timer handler
+    build.enter(debug=mpi.rank == 0),  # Parse compiled objects
+    mpi.enter(pm),  # Initialize MPI in the PM module
+    mym.enter(*build.components),  # Allocate 2GB memory
+    p,  # Allocate particle data structure in MyMalloc
+    ic.enter(p, mpi.ranks, p.get_maxpart(), ts.G),  # Sample NFW profile
+    pm,  # Initialize PM and compute first accelerations
+    ts  # Compute DriftTables if needed
+):
+
+    #
+    # Step 3: Main simulation loop
+    #
+    while ts.time < ts.time_end:
+        ts.find_timesteps()  # Determine timesteps
+        ts.do_first_halfstep_kick()  # First kick (includes drift/kick callbacks)
+        ts.drift()  # Update particle positions
+        pm.compute_accelerations()  # Recompute accelerations
+        ts.do_second_halfstep_kick()  # Second kick
+
+        # Occasionally, generate plots on the master rank
+        if mpi.rank == 0 and ts.steps % 10 == 0:
+            fig, ax = plt.subplots(1)
+            ax.hist2d(p['pos'][:, 0], p['pos'][:, 1], bins=128)
+            ax.set_aspect('equal')
+            fig.savefig(f'snap{ts.steps}_rank{mpi.rank}.png', bbox_inches='tight', dpi=200)
+            plt.close(fig)
+
+print('Simulation finished')
diff --git a/test_editable.bash b/test_editable.bash
index 42fe3c7..a44a640 100755
--- a/test_editable.bash
+++ b/test_editable.bash
@@ -1,8 +1,9 @@
-git clone ssh://git@git.ia2.inaf.it/hotwheels/timestep.git
-cd timestep
+git clone ssh://git@git.ia2.inaf.it/hotwheels/integrate.git
+cd integrate
 # very IMPORTANT the -e will install in editable mode
 pip install -e . 
 #
 # edit the files of your choice. Edits will take effect
 # without the need of re-installing the package
 #
+cd ..
diff --git a/test_install_pm.bash b/test_install_pm.bash
new file mode 100644
index 0000000..c240626
--- /dev/null
+++ b/test_install_pm.bash
@@ -0,0 +1 @@
+pip install 'hotwheels_PM[tested] @ git+ssh://git@git.ia2.inaf.it/hotwheels/PM.git@v0.0.2alpha'
diff --git a/test_pip_all.bash b/test_pip_all.bash
index 356cabb..aff7760 100755
--- a/test_pip_all.bash
+++ b/test_pip_all.bash
@@ -1,6 +1,6 @@
 pip install git+ssh://git@git.ia2.inaf.it/hotwheels/core.git@v0.0.2alpha
 pip install git+ssh://git@git.ia2.inaf.it/hotwheels/io.git@v0.0.2alpha
-pip install git+ssh://git@git.ia2.inaf.it/hotwheels/timestep.git@v0.0.2alpha
+pip install git+ssh://git@git.ia2.inaf.it/hotwheels/integrate.git@v0.0.2alpha
 pip install git+ssh://git@git.ia2.inaf.it/hotwheels/octree.git@v0.0.2alpha
 pip install git+ssh://git@git.ia2.inaf.it/hotwheels/domain.git@v0.0.2alpha
 pip install git+ssh://git@git.ia2.inaf.it/hotwheels/PM.git@v0.0.2alpha
-- 
GitLab