From 9d61a4593b166bac09569d41e57327638cefb6bb Mon Sep 17 00:00:00 2001 From: Alessandro Aimi Date: Thu, 9 Nov 2023 08:24:23 +0100 Subject: [PATCH] Reproduce ns-3 CI pipelines (push, MR) (#141) --- .github/actions/build/action.yml | 44 +++++++++++ .github/actions/checkout-in-ns3/action.yml | 18 +++++ .github/actions/install-analysis/action.yml | 21 ++++++ .github/actions/install-doc/action.yml | 28 +++++++ .github/actions/install-linting/action.yml | 21 ++++++ .github/actions/install-per-commit/action.yml | 24 ++++++ .github/actions/test/action.yml | 14 ++++ .github/workflows/.doc.yml | 61 ++++++++++++++++ .github/workflows/.formatting.yml | 68 +++++++++++++++++ .github/workflows/.linting.yml | 50 +++++++++++++ .github/workflows/analysis.yml | 71 ++++++++++++++++++ .github/workflows/deploy-doc.yml | 42 +++++++++++ .github/workflows/deploy-docs.yml | 47 ------------ .github/workflows/per-commit.yml | 73 +++++++++++++++++++ .github/workflows/run-tests.yml | 33 --------- 15 files changed, 535 insertions(+), 80 deletions(-) create mode 100644 .github/actions/build/action.yml create mode 100644 .github/actions/checkout-in-ns3/action.yml create mode 100644 .github/actions/install-analysis/action.yml create mode 100644 .github/actions/install-doc/action.yml create mode 100644 .github/actions/install-linting/action.yml create mode 100644 .github/actions/install-per-commit/action.yml create mode 100644 .github/actions/test/action.yml create mode 100644 .github/workflows/.doc.yml create mode 100644 .github/workflows/.formatting.yml create mode 100644 .github/workflows/.linting.yml create mode 100644 .github/workflows/analysis.yml create mode 100644 .github/workflows/deploy-doc.yml delete mode 100644 .github/workflows/deploy-docs.yml create mode 100644 .github/workflows/per-commit.yml delete mode 100644 .github/workflows/run-tests.yml diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml new file mode 100644 index 0000000000..df309770ca --- /dev/null +++ b/.github/actions/build/action.yml @@ -0,0 +1,44 @@ +name: "build" +description: "Defines the central steps in building ns-3" + +inputs: + save-ccache: + description: "Whether to update build ccache after building" + default: "true" + store-artifacts: + description: "Whether to upload build artifacts after building" + default: "true" + +runs: + using: "composite" + steps: + # Pre-configuration steps + - if: env.MODE != 'optimized' && ( ! contains(env.EXTRA_OPTIONS, '--disable-precompiled-headers') ) + name: "Restore build cache of this job" + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ env.BUILD_ID }} + save: ${{ inputs.save-ccache }} + # Configuration steps + - name: "Configure ns-3 CMake" + shell: bash + run: > + CXX=$COMPILER ./ns3 configure -d $MODE -GNinja + --enable-examples --enable-tests --enable-asserts --enable-werror + --enable-modules "lorawan;applications" $EXTRA_OPTIONS + # Build steps + - name: "Build ns-3" + shell: bash + run: ./ns3 build + # Post-build steps + - if: inputs.store-artifacts == 'true' + name: "Tar files to preserve permissions" + shell: bash + run: tar -cf build.tzst --exclude build.tzst -P -C $GITHUB_WORKSPACE --use-compress-program zstdmt build/ .lock-* + - if: inputs.store-artifacts == 'true' + name: "Upload build artifacts" + uses: actions/upload-artifact@v3.0.0 + with: + name: ${{ env.BUILD_ID }} + path: build.tzst + retention-days: 2 diff --git a/.github/actions/checkout-in-ns3/action.yml b/.github/actions/checkout-in-ns3/action.yml new file mode 100644 index 0000000000..54bba04361 --- /dev/null +++ b/.github/actions/checkout-in-ns3/action.yml @@ -0,0 +1,18 @@ +name: "checkout-in-ns3" +description: "Checkout this repository as ns-3 module" + +# Requires wget! + +runs: + using: "composite" + steps: + - name: "Checkout this repository as ns-3 module" + uses: actions/checkout@v4 + with: + path: "src/lorawan" + - name: "Download ns-3-dev working tree with Gitlab API" + run: | + tag=$(< src/lorawan/NS3-VERSION) && tag=${tag#release } + wget -nv -O ns-3-dev.tar https://gitlab.com/api/v4/projects/nsnam%2Fns-3-dev/repository/archive.tar?sha=$tag + tar -xf ns-3-dev.tar && cp -a ns-3-dev-$tag-*/. . && rm -R ns-3-dev.tar ns-3-dev-$tag* + shell: bash diff --git a/.github/actions/install-analysis/action.yml b/.github/actions/install-analysis/action.yml new file mode 100644 index 0000000000..8a31ac022a --- /dev/null +++ b/.github/actions/install-analysis/action.yml @@ -0,0 +1,21 @@ +# Note: this action requires an ubuntu container and access to the repos's actions! +# (see analysis.yml) +name: "install-analysis" +description: "Installs required ubuntu packages and checks-out the repo in ns-3" + +runs: + using: "composite" + steps: + - name: "Install required system packages" + shell: bash + run: > + sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y + apt-utils + git gcc g++ cmake python3 make ninja-build + tcpdump libgsl-dev libxml2-dev + curl unzip tar + ccache + lcov + wget + - name: "Checkout this repository as ns-3 module" + uses: ./.github/actions/checkout-in-ns3 diff --git a/.github/actions/install-doc/action.yml b/.github/actions/install-doc/action.yml new file mode 100644 index 0000000000..1639b3b682 --- /dev/null +++ b/.github/actions/install-doc/action.yml @@ -0,0 +1,28 @@ +# Note: this action requires an archlinux container and access to the repos's actions! +# (see .doc.yml) +name: "install-doc" +description: "Installs required archlinux packages and checks-out the repo in ns-3" + +runs: + using: "composite" + steps: + - name: "Install required system packages" + shell: bash + run: > + pacman-key --init && pacman -Syu --noconfirm + base-devel ninja cmake python ccache gsl gtk3 boost openssh + graphviz imagemagick texlive-basic texlive-bin texlive-binextra texlive-latexextra + texlive-fontutils texlive-fontsrecommended python-sphinx + wget && + pacman --noconfirm -U https://archive.archlinux.org/packages/d/dia/dia-0.97.3-9-x86_64.pkg.tar.zst && + pacman --noconfirm -U https://archive.archlinux.org/packages/d/doxygen/doxygen-1.9.6-1-x86_64.pkg.tar.zst && + mv /etc/ImageMagick-7/policy.xml /etc/ImageMagick-7/policy.xml.bak + - name: "Checkout this repository as ns-3 module" + uses: ./.github/actions/checkout-in-ns3 + - name: "Add lorawan module to docs" + shell: bash + working-directory: doc/models + run: | + sed -i '/lr-wpan\/doc\/lr-wpan.rst/a\\t\$(SRC)\/lorawan\/doc\/lorawan.rst \\' Makefile + sed -i '/lr-wpan\/doc\/lr-wpan-arch.dia/i\\t\$(SRC)\/lorawan\/doc\/figures\/LoRaWANTopology.pdf \\' Makefile + sed -i '/lr-wpan/i\ lorawan' source/index.rst diff --git a/.github/actions/install-linting/action.yml b/.github/actions/install-linting/action.yml new file mode 100644 index 0000000000..62fc61ee37 --- /dev/null +++ b/.github/actions/install-linting/action.yml @@ -0,0 +1,21 @@ +# Note: this action requires an ubuntu container and access to the repos's actions! +# (see .linting.yml) +name: "install-linting" +description: "Installs required ubuntu packages and checks-out the repo in ns-3" + +runs: + using: "composite" + steps: + - name: "Install required system packages" + shell: bash + run: > + apt update && DEBIAN_FRONTEND=noninteractive apt install -y + clang cmake + clang-tidy clang-tidy-16 + python3 python3-pip + libboost-all-dev libeigen3-dev libgtk-3-dev libsqlite3-dev + gsl-bin libgsl-dev libgsl27 + git ssh + wget + - name: "Checkout this repository as ns-3 module" + uses: ./.github/actions/checkout-in-ns3 diff --git a/.github/actions/install-per-commit/action.yml b/.github/actions/install-per-commit/action.yml new file mode 100644 index 0000000000..f2d962cb56 --- /dev/null +++ b/.github/actions/install-per-commit/action.yml @@ -0,0 +1,24 @@ +# Note: this action requires an archlinux container, specific inputs and access to the repos's actions! +# (see .base-per-commit.yml) +name: "install-per-commit" +description: "Installs required archlinux packages and checks-out the repo in ns-3" + +runs: + using: "composite" + steps: + - name: "Install required system packages" + shell: bash + run: > + pacman-key --init && pacman -Syu --noconfirm + base-devel gcc clang cmake ninja ccache + boost gsl gtk3 + openssh + python + wget + - name: "Checkout this repository as ns-3 module" + uses: ./.github/actions/checkout-in-ns3 + - name: "Format a string id for the build conf. of this job" + shell: bash + run: | + EXTRA_ID=`echo $EXTRA_OPTIONS | sed 's/--/-/g' | sed 's/ //g'` + echo "BUILD_ID=per-commit-$COMPILER-$MODE$EXTRA_ID" >> $GITHUB_ENV diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml new file mode 100644 index 0000000000..77395cb4ff --- /dev/null +++ b/.github/actions/test/action.yml @@ -0,0 +1,14 @@ +name: "test" +description: "Defines the central steps in testing ns-3" + +runs: + using: "composite" + steps: + # Test steps + - name: "Store ccache miss rate" + shell: bash + run: echo "CACHE_MISS=`./utils/ccache-miss-rate.py`" >> $GITHUB_ENV + - if: env.CACHE_MISS != '0' && env.MODE != 'debug' + name: "Test ns-3" + shell: bash + run: ./test.py -n diff --git a/.github/workflows/.doc.yml b/.github/workflows/.doc.yml new file mode 100644 index 0000000000..85a5cf8374 --- /dev/null +++ b/.github/workflows/.doc.yml @@ -0,0 +1,61 @@ +# Base ns-3 CI job template for per-commit jobs involving building and testing + +on: workflow_call + +jobs: + doxygen: + runs-on: ubuntu-latest + container: + image: archlinux + timeout-minutes: 120 + continue-on-error: true + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-doc + - name: "Build ns-3" + env: + BUILD_ID: per-commit-g++-debug + COMPILER: g++ + MODE: debug + uses: ./.github/actions/build + with: + save-ccache: "false" + store-artifacts: "false" + - name: "Build ns-3 assemble-introspected-command-line" + run: ./ns3 build assemble-introspected-command-line + - name: "Check documentation coverage and formatting" + run: | + doc/doxygen.warnings.report.sh -i -m lorawan + python3 utils/check-style-clang-format.py --no-formatting --no-tabs doc/introspected-doxygen.h + python3 utils/check-style-clang-format.py --no-formatting --no-tabs doc/introspected-command-line.h + ./ns3 clean + - name: "Upload doxygen warnings as artifact" + if: always() + uses: actions/upload-artifact@v3.0.0 + with: + name: doxygen.warnings.log + path: doc/doxygen.warnings.log + + models: + runs-on: ubuntu-latest + container: + image: archlinux + timeout-minutes: 120 + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-doc + - name: "Make html and latexpdf" + working-directory: doc/models + run: | + make html + make latexpdf diff --git a/.github/workflows/.formatting.yml b/.github/workflows/.formatting.yml new file mode 100644 index 0000000000..a27c233dbc --- /dev/null +++ b/.github/workflows/.formatting.yml @@ -0,0 +1,68 @@ +# ns-3 CI/CD script with the pre-build stage +# +# Contains jobs to check the ns-3 code formatting and spell-checking. + +on: workflow_call + +jobs: + # Clang-format + check-style-clang-format: + runs-on: ubuntu-latest + container: + image: ubuntu:rolling + strategy: + matrix: + version: [14, 15, 16] + timeout-minutes: 60 + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install required system packages" + run: > + apt update && DEBIAN_FRONTEND=noninteractive apt install -y + python3 + clang-format-${{ matrix.version }} + wget + - name: "Checkout this repository as ns-3 module" + uses: ./.github/actions/checkout-in-ns3 + - name: "Check code style" + run: python3 utils/check-style-clang-format.py --verbose src/lorawan + + # Emacs line + emacs-line: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - run: > + if ( egrep -rn --include="*.h" --include="*.cc" --include="*.c" --include="*.py" --include="*.rst" "c-file-style:|py-indent-offset:" ) ; then + echo "Found Emacs lines on the above C/C++, Python and RST files" ; + exit 1 ; + else + echo "No Emacs lines found on C/C++, Python and RST files" ; + exit 0 ; + fi + + # Spell checking + spell-check: + runs-on: ubuntu-latest + container: + image: python:latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - run: pip install codespell + # Get commit messages + - run: > + if (git remote | grep -qw upstream) ; then + git remote remove upstream ; + fi + - run: git config --global --add safe.directory $GITHUB_WORKSPACE + # develop here is meant to be the "default branch" + - run: git remote add -t develop --no-tags -f upstream https://github.com/signetlabdei/lorawan.git + - run: git log --pretty=%B HEAD...upstream/develop ^upstream/develop > git_messages.txt + # Check source code and commit messages + - run: codespell -f -C0 --skip="./experiments" ./ diff --git a/.github/workflows/.linting.yml b/.github/workflows/.linting.yml new file mode 100644 index 0000000000..6ffeba824d --- /dev/null +++ b/.github/workflows/.linting.yml @@ -0,0 +1,50 @@ +# ns-3 CI/CD script with jobs of the code-linting stage +# +# Contains jobs to perform lint checking. + +on: workflow_call + +jobs: + # Clang-tidy + clang-tidy-16: + runs-on: ubuntu-latest + container: + image: ubuntu:rolling + timeout-minutes: 180 + env: + CLANG_TIDY_OUTPUT: clang-tidy-output.log + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-linting + - name: "Configure ns-3 CMake" + run: > + ./ns3 configure -d debug + --enable-examples --enable-tests --enable-asserts + --enable-modules "lorawan;applications" + --enable-clang-tidy + # Use a trick (git diff on empty tag) to only run clang-tidy on the lorawan module + - name: "Running clang-tidy" + shell: bash + run: > + git -C src/lorawan/ tag empty $(git hash-object -t tree /dev/null) && + git -C src/lorawan/ diff -U0 empty + --src-prefix=a/src/lorawan/ --dst-prefix=b/src/lorawan/ | + clang-tidy-diff-16.py -path cmake-cache/ -p1 -quiet -use-color + -iregex "src\/lorawan\/.+\.(cpp|cc|cxx|c|h|hpp)" + 1> $CLANG_TIDY_OUTPUT + 2> /dev/null + - name: "Check job results" + run: | + (! egrep -A 3 "error:|warning:|note:" $CLANG_TIDY_OUTPUT) + echo "No clang-tidy errors found" + - if: failure() + name: "Upload clang-tidy-output.log" + uses: actions/upload-artifact@v3.0.0 + with: + name: ${{ env.CLANG_TIDY_OUTPUT }} + path: ${{ env.CLANG_TIDY_OUTPUT }} diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml new file mode 100644 index 0000000000..415df22e69 --- /dev/null +++ b/.github/workflows/analysis.yml @@ -0,0 +1,71 @@ +# ns-3 CI/CD script with job for code quality and coverage +# +# Contains jobs to run code quality and coverage analysis. + +on: + workflow_call: + workflow_dispatch: + +env: + COMPILER: g++ + MODE: default + +jobs: + # CodeQL + code-ql: + runs-on: ubuntu-latest + continue-on-error: true + steps: + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: "cpp" + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-analysis + - name: "Build ns-3" + env: + BUILD_ID: ubuntu-codeql + COMPILER: g++ + MODE: release + EXTRA_OPTIONS: --disable-werror + uses: ./.github/actions/build + with: + store-artifacts: "false" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + checkout_path: ${{ github.workspace }}/src/lorawan + + # CodeCov + code-cov: + runs-on: ubuntu-latest + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-analysis + - name: "Build ns-3" + env: + BUILD_ID: ubuntu-coverage + COMPILER: g++ + MODE: release + EXTRA_OPTIONS: --disable-werror --enable-gcov + uses: ./.github/actions/build + with: + store-artifacts: "false" + - name: "Extract ccache statistics" + run: echo "CACHE_MISSES=`./utils/ccache-miss-rate.py`" >> $GITHUB_ENV + - if: env.CACHE_MISSES != '0' + name: "Generate coverage data and submit to codecov.io" + run: | + ./ns3 build coverage_gcc + bash <(curl -s https://codecov.io/bash) -f build/coverage/ns3.info -R src/lorawan/ || echo "Codecov did not collect coverage reports" diff --git a/.github/workflows/deploy-doc.yml b/.github/workflows/deploy-doc.yml new file mode 100644 index 0000000000..1e5c79f5f6 --- /dev/null +++ b/.github/workflows/deploy-doc.yml @@ -0,0 +1,42 @@ +# CI job to deploy the documentation on another repository + +on: + workflow_call: + workflow_dispatch: + +jobs: + deploy-doc: + runs-on: ubuntu-latest + container: + image: archlinux + timeout-minutes: 120 + continue-on-error: true + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-doc + - name: "Build ns-3" + env: + BUILD_ID: per-commit-g++-debug + COMPILER: g++ + MODE: debug + uses: ./.github/actions/build + with: + save-ccache: "false" + store-artifacts: "false" + - name: "Build documentation" + run: ./ns3 docs all + - name: "Deploy documentation" + env: + SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} + uses: cpina/github-action-push-to-another-repository@main + with: + source-directory: "doc/" + destination-github-username: "signetlabdei" + destination-repository-name: "lorawan-docs" + user-email: paginmatte@dei.unipd.it + target-branch: master diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml deleted file mode 100644 index 974cf80d6f..0000000000 --- a/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Build and deploy docs - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - workflow_dispatch: - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - name: Clone ns-3 - run: git clone https://gitlab.com/nsnam/ns-3-dev - - uses: actions/checkout@v2 - with: - path: 'ns-3-dev/src/lorawan' - - name: Install dependencies needed to generate docs - run: | - sudo apt-get update - sudo apt-get install dia doxygen sphinx-doc sphinx-common python3-pydot texlive-full latexmk dvipng texlive-font-utils - sudo rm /etc/ImageMagick-*/policy.xml - - name: Build docs - run: | - cd ns-3-dev/ - cp utils/.ns3rc ./ - sed -i "s/all_modules/lorawan/" .ns3rc - sed -i "s/False/True/" .ns3rc - ./ns3 configure - ./ns3 docs all - - name: Pushes to another repository - uses: cpina/github-action-push-to-another-repository@main - env: - API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} - with: - source-directory: 'docs/' - destination-github-username: 'signetlabdei' - destination-repository-name: 'lorawan-docs' - user-email: magrin.davide@gmail.com - target-branch: master diff --git a/.github/workflows/per-commit.yml b/.github/workflows/per-commit.yml new file mode 100644 index 0000000000..b98150ce97 --- /dev/null +++ b/.github/workflows/per-commit.yml @@ -0,0 +1,73 @@ +name: "Per-commit ns-3 CI jobs" +run-name: "per-commit" + +on: + push: + branches: [develop] + pull_request: + branches: [develop] + workflow_dispatch: + +jobs: + code-formatting: + uses: ./.github/workflows/.formatting.yml + + compile: + needs: code-formatting + runs-on: ubuntu-latest + container: + image: archlinux + timeout-minutes: 720 + strategy: + matrix: + compiler: [g++] + mode: [default, optimized] + stage: [test] + include: + - compiler: clang++ + mode: debug + - compiler: g++ + mode: debug + - compiler: g++ # this job is the longest (~ 30 min) + mode: debug + extra_options: --disable-precompiled-headers + - compiler: g++ + mode: debug + extra_options: --disable-asserts + env: + COMPILER: ${{ matrix.compiler }} + MODE: ${{ matrix.mode }} + EXTRA_OPTIONS: ${{ matrix.extra_options }} + steps: + # The following step is required in all jobs that use this repo's actions + - name: "Retrieve actions from repository" + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + - name: "Install dependencies and checkout repo in ns-3" + uses: ./.github/actions/install-per-commit + - name: "Build ns-3" + uses: ./.github/actions/build + - if: matrix.stage == 'test' + name: "Test ns-3" + uses: ./.github/actions/test + + code-linting: + needs: compile + uses: ./.github/workflows/.linting.yml + + documentation: + needs: code-linting + uses: ./.github/workflows/.doc.yml + + code-analysis: + needs: documentation + uses: ./.github/workflows/analysis.yml + secrets: inherit + + deploy-doc: + # do not run on PR events + if: github.event_name == 'push' + needs: documentation + uses: ./.github/workflows/deploy-doc.yml + secrets: inherit diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index 5f41dcd6dd..0000000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Build and run tests - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - workflow_dispatch: - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - name: Clone ns-3 - run: git clone https://gitlab.com/nsnam/ns-3-dev - - uses: actions/checkout@v2 - with: - path: 'ns-3-dev/src/lorawan' - - name: Compile and run tests - run: | - cd ns-3-dev/ - cp utils/.ns3rc ./ - sed -i "s/all_modules/lorawan/" .ns3rc - sed -i "s/False/True/" .ns3rc - ./ns3 configure - ./ns3 build - ./test.py -n -s lorawan