Skip to content

Commit

Permalink
Release v1
Browse files Browse the repository at this point in the history
  • Loading branch information
emanuelegiona committed Sep 10, 2023
1 parent d111547 commit 47b651c
Show file tree
Hide file tree
Showing 3 changed files with 340 additions and 1 deletion.
174 changes: 173 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,174 @@
# ns3-compatibility-action
Custom GitHub Action for testing one or more modules against a specific ns-3 version
Custom GitHub Action for testing one or more modules against a specific [ns-3][ns3] version.

## Rationale

The development of ns-3 is an effort by large community, with both the base simulator and third-party modules evolving at a fast pace.
This is the result of ns-3 being widely used in research performed at both industry and academia worldwide.

This GitHub action aims at supporting the development of new modules, ensuring compatibility guarantees against multiple ns-3 versions by leveraging CI/CD pipelines.

## Usage guidelines

**Inputs**

- `ns3_docker_img` (**Required**)

[Docker][docker] image in the format _name:tag_ containing an installation of the desired ns-3 version to test against.

*Image requirements*

- Existence of a `/home` directory in resulting containers

- `bash` shell support

- `tar` package availability

- Refrain from using `ns3-container` as Docker container name within a same action runner

> Any Docker image available to the action runner is supported.
> A useful selection of images spanning across several ns-3 versions is found at [egiona/ns3-woss][ns3-woss-docker]. These images provide _already-built_ ns-3 installations bundling the [World Ocean Simulation System][woss] library, as well as some utility scripts.
Being pre-built in _debug_ profile, these images greatly reduce the testing time for your module(s).

- `test_script` (**Required**)

Path to an installation & testing bash script, relatively to the _root of the action-invoking repository_.

*Script requirements*

- This script should perform any installation step required by the modules intended to be tested, and optionally run the desired test suite(s)

- Creation of a file at container's path `/home/exit-code.txt` ; this file should consist in either `0` or `1`, respectively indicating a successful installation & testing or not

- Creation of a file at container's path `/home/test-output.txt` ; this file should consist of a textual message to print as an additional explanation to tests' outcome (_i.e._ it can be empty, but it is necessary nonetheless)

- This script should \_NOT\_ contain the final `exit` bash instruction as to avoid unintended failures of `docker exec` ; exit status should be reported by means of the `/home/exit-code.txt` file

> This script is run inside the container created from the provided image.
Contents of the repository this action is invoked from are copied as a compressed archive at container's path `/home/ns3-module-repo.tar.gz` and then unpacked.
This argument should thus point at _source-able_ bash script within container's directory `/home/ns3-module-repo/`.

**Outputs**

- `result`

Values: `success` | `failure`

Storage: `$GITHUB_OUTPUT`

## Workflow example

Testing a module `my-module` for ns-3 compatibility against versions 3.33 and 3.37 after each tag is pushed to the repository.
Docker images employed are [`egiona/ns3-woss:u18.04-n3.33-w1.12.1-r2`][img3.33] and [`egiona/ns3-woss:u18.04-n3.37-w1.12.4-r2`][img3.37], respectively.

Repository structure:
```
my-module/
doc/
...
examples/
...
helper/
...
model/
...
test/
...
CMakeLists.txt
wscript
test-ns3.sh
```

`check-compatibility.yml` file:
```
on:
push:
tags:
- '*'
jobs:
ns3_33_check:
runs-on: ubuntu-latest
name: ns-3.33 compatibility check
steps:
- name: ns3-compatibility-action
uses: emanuelegiona/ns3-compatibility-action@v1
with:
ns3_docker_img: egiona/ns3-woss:u18.04-n3.33-w1.12.1-r2
test_script: test-ns3.sh
ns3_37_check:
runs-on: ubuntu-latest
name: ns-3.37 compatibility check
steps:
- name: ns3-compatibility-action
uses: emanuelegiona/ns3-compatibility-action@v1
with:
ns3_docker_img: egiona/ns3-woss:u18.04-n3.37-w1.12.4-r2
test_script: test-ns3.sh
```

`test-ns3.sh` file:
```
#!/bin/bash
# Prepare output files
OUTCOME=1
echo "${OUTCOME}" > /home/exit-code.txt
echo "my-module-test: Test not run" > /home/test-output.txt
# Install module into ns-3 "contrib" tree using the Makefile (assumption: working directory is the same as this file)
OUTCOME=1
cp -r my-module /home/
cd /home
# Ensure debug profile _before_ copying module
export NS3_CURR_PROFILE=${NS3_DEBUG_DIR}
make sync_module FILE=my-module
# Necessary to avoid killing docker parent processes (build scripts send USR1 signal in interactive shells)
trap "echo Ignoring USR1" USR1
./build-debug.sh && OUTCOME=0
if [[ "$OUTCOME" -eq 1 ]]; then
echo "Error: build failed"
else
# Run module-specific tests and retain their outputs
OUTCOME=1
make test SUITE=my-module-test LOG=/home/test-tmp && \
OUTCOME=0
if [[ "$OUTCOME" -eq 1 ]]; then
echo "Error: tests failed"
fi
fi
# Update "test-output.txt" with tests execution details
cat /home/test-tmp.txt > /home/test-output.txt
# Only return success if all previous commands executed correctly
echo "${OUTCOME}" > /home/exit-code.txt
# === No exit here ===
# Avoids exiting the entrypoint sub-script from GitHub action that sources this file
```
> Note: this `test-ns3.sh` script applies to the employed Docker images only, and assuming an implemented ns-3 test suite named `my-module-test`.
## License

**Copyright (c) 2023 Emanuele Giona**

This repository, scripts and snippets themselves are distributed under [MIT license][license].

**Diclaimer: Docker, Ubuntu, ns-3, WOSS and other cited or included software belongs to their respective owners.**



[ns3]: https://www.nsnam.org/
[ns3-changelog]: https://gitlab.com/nsnam/ns-3-dev/-/blob/master/CHANGES.md
[docker]: https://www.docker.com/
[ns3-woss-docker]: https://github.com/SENSES-Lab-Sapienza/ns3-woss-docker
[woss]: https://woss.dei.unipd.it/
[img3.33]: https://github.com/SENSES-Lab-Sapienza/ns3-woss-docker/blob/main/u18.04-n3.33-w1.12.1-r2/Dockerfile
[img3.37]: https://github.com/SENSES-Lab-Sapienza/ns3-woss-docker/blob/main/u18.04-n3.37-w1.12.4-r2/Dockerfile
[license]: ./LICENSE
54 changes: 54 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# MIT License

# Copyright (c) 2023 Emanuele Giona

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

name: ns3-compatibility-action
description: Custom GitHub Action for testing one or more modules against a specific ns-3 version
author: Emanuele Giona
inputs:
ns3_docker_img:
description: Docker image in the format name:tag containing an installation of the desired ns-3 version
required: true
default: ""
test_script:
description: Path to an installation & testing bash script, relatively to the root of the action-invoking repository
required: true
default: ""

outputs:
result:
description: Action execution outcome

runs:
using: 'composite'
steps:
- name: Checkout
uses: actions/checkout@v4.0.0
- name: Action runner script
env:
INPUT_NS3_DOCKER_IMG: ${{ inputs.ns3_docker_img }}
INPUT_TEST_SCRIPT: ${{ inputs.test_script }}
run: ${{ github.action_path }}/runner.sh
shell: bash

branding:
icon: "check-circle"
color: "green"
113 changes: 113 additions & 0 deletions runner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# MIT License

# Copyright (c) 2023 Emanuele Giona

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

#/bin/bash

if [[ -z "$INPUT_NS3_DOCKER_IMG" ]]; then
echo "Error: no Docker image provided"
exit 1
fi

if [[ -z "$INPUT_TEST_SCRIPT" ]]; then
echo "Error: no installation & testing script provided"
exit 1
fi

# Create entrypoint.sh script for later usage within Docker container
cat >entrypoint.sh <<'EOL'
#!/bin/bash
cd /home
# Unpack contents of current repository's root directory
ARCHIVE_NAME="${ROOT_REPO_DIR}.tar.gz"
tar -xf "/home/${ARCHIVE_NAME}"
# Run user-provided installation & testing script
cd "${ROOT_REPO_DIR}" && . "${TEST_SCRIPT}" && \
exit 0
EOL
chmod +x entrypoint.sh

# Fetch the specified Docker image
OUTCOME=1
docker pull $INPUT_NS3_DOCKER_IMG && OUTCOME=0

if [[ "$OUTCOME" -eq 1 ]]; then
echo "Error: docker pull ${INPUT_NS3_DOCKER_IMG} failed"
exit 1
fi

# Prepare user module repository contents for their copy into a container
REPO_DIR="ns3-module-repo"
shopt -s extglob
mkdir "$REPO_DIR"
cp -r !("$REPO_DIR") "$REPO_DIR/"
tar -cf "$REPO_DIR.tar.gz" "$REPO_DIR"

# Start a container from the specific image
OUTCOME=1
CONTAINER_NAME="ns3-container"
docker run \
-e ROOT_REPO_DIR="${REPO_DIR}" \
-e TEST_SCRIPT="${INPUT_TEST_SCRIPT}" \
-td \
--name "$CONTAINER_NAME" "$INPUT_NS3_DOCKER_IMG" && OUTCOME=0

if [[ "$OUTCOME" -eq 1 ]]; then
echo "Error: docker run ${INPUT_NS3_DOCKER_IMG} failed"
exit 1
fi

# Copy entryscript and repository contents into the container
docker cp entrypoint.sh "$CONTAINER_NAME:/home/entrypoint.sh"
docker cp "$REPO_DIR.tar.gz" "$CONTAINER_NAME:/home/"

# Finally execute the installation & testing script
OUTCOME=1
docker exec "$CONTAINER_NAME" "./home/entrypoint.sh" && OUTCOME=0

if [[ "$OUTCOME" -eq 1 ]]; then
echo "Error: docker exec failed"
exit 1
fi

# Parse execution & test outputs
docker cp "$CONTAINER_NAME:/home/exit-code.txt" ./exit-code.txt
docker cp "$CONTAINER_NAME:/home/test-output.txt" ./test-output.txt
OUTCOME=$(cat exit-code.txt)

# Cleanup Docker container
docker kill "$CONTAINER_NAME" && \
docker rm "$CONTAINER_NAME"

if [[ "$OUTCOME" -eq 0 ]]; then
echo "Action completed successfully"
echo "result=success" >> "$GITHUB_OUTPUT"
else
echo "Action failed"
echo "result=failure" >> "$GITHUB_OUTPUT"
fi

echo "=== Test outputs ==="
cat test-output.txt
echo "=== ===== ===== ==="
exit $OUTCOME

0 comments on commit 47b651c

Please sign in to comment.