From f82286c7e4a98a2d1bf32526afa769f7932f273e Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 18:50:17 -0800 Subject: [PATCH 001/135] [TESTS] Fix for GH issue #1 (travis-ci paywall bypass) --- .github/workflows/Tests.yml | 28 +++++++++++++++++++++++----- README.md | 4 +--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index ac35d01a..2331fca7 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -1,20 +1,38 @@ name: CI - on: [push] - jobs: MATS: - runs-on: ubuntu-latest - + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + env: + OS: ${{ matrix.os }} + PYTHON: '3.9' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@master + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: 3.9 - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests run: | echo Testing M.A.T.s, make -j1 -f Makefile test || true + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v2 + with: + directory: ./coverage/reports/ + env_vars: OS,PYTHON + fail_ci_if_error: true + files: ./coverage1.xml,./coverage2.xml + flags: unittests + name: codecov-umbrella + path_to_write_report: ./coverage/codecov_report.txt + verbose: true - name: Post-Clean run: make -j1 -f Makefile clean || true ; diff --git a/README.md b/README.md index d81f3a54..b97dde6b 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,11 @@ concurently without individual conections for each node pair. # CI (WIP): -Continuous integration testing is handeled by Travis CI Service and Circle-CI Service. +Continuous integration testing is handeled by Circle-CI Service. ## Status ### master: -[![Status](https://travis-ci.org/reactive-firewall/multicast.svg?branch=master)](https://travis-ci.org/reactive-firewall/multicast) [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) [![Appveyor](https://ci.appveyor.com/api/projects/status/??????/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) [![Test Coverage](https://api.codeclimate.com/v1/badges/?????/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) @@ -26,7 +25,6 @@ Continuous integration testing is handeled by Travis CI Service and Circle-CI Se ![Commits-since](https://img.shields.io/github/commits-since/reactive-firewall/multicast/stable.svg?maxAge=9000) ### Stable: -[![Stable-Status](https://travis-ci.org/reactive-firewall/multicast.svg?branch=stable)](https://travis-ci.org/reactive-firewall/multicast) [![Stable-CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/stable.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/stable) [![Atable-Appveyor](https://ci.appveyor.com/api/projects/status/????/branch/stable?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/stable) [![stable-code-coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/) From dcc18b1f11900d952c55a76d4a301bc42a9f8e09 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 21:28:25 -0800 Subject: [PATCH 002/135] [STYLE] Added corrected Code Climate Badges to readme --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b97dde6b..e9e6eee3 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,9 @@ Continuous integration testing is handeled by Circle-CI Service. ### master: [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) [![Appveyor](https://ci.appveyor.com/api/projects/status/??????/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) -[![Test Coverage](https://api.codeclimate.com/v1/badges/?????/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) +[![Test Coverage](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) [![Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/master/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/master/) -[![Coverage Status](https://coveralls.io/repos/github/reactive-firewall/multicast/badge.svg?branch=master)](https://coveralls.io/github/reactive-firewall/multicast?branch=master) -[![Coverity](https://scan.coverity.com/projects/????/badge.svg)](https://scan.coverity.com/projects/reactive-firewall-multicast) -[![Code Climate](https://codeclimate.com/github/reactive-firewall/multicast/badges/gpa.svg)](https://codeclimate.com/github/reactive-firewall/multicast) +[![Code Climate](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/maintainability)](https://codeclimate.com/github/reactive-firewall/multicast) [![CodeFactor](https://www.codefactor.io/repository/github/reactive-firewall/multicast/badge)](https://www.codefactor.io/repository/github/reactive-firewall/multicast) [![Codebeat badge](https://codebeat.co/badges/?????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-master) ![Size](https://img.shields.io/github/languages/code-size/reactive-firewall/multicast.svg) @@ -28,7 +26,6 @@ Continuous integration testing is handeled by Circle-CI Service. [![Stable-CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/stable.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/stable) [![Atable-Appveyor](https://ci.appveyor.com/api/projects/status/????/branch/stable?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/stable) [![stable-code-coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/) -[![Stable Coverage Status](https://coveralls.io/repos/github/reactive-firewall/multicast/badge.svg?branch=stable)](https://coveralls.io/github/reactive-firewall/multicast?branch=stable) [![Staqble Codebeat Badge](https://codebeat.co/badges/????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-stable) # How do I get this running? From 1ac5228e213a4d0531a49bfcb0314482cbcdd633 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 21:28:25 -0800 Subject: [PATCH 003/135] [STYLE] Added corrected Code Climate Badges to readme --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b97dde6b..e9e6eee3 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,9 @@ Continuous integration testing is handeled by Circle-CI Service. ### master: [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) [![Appveyor](https://ci.appveyor.com/api/projects/status/??????/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) -[![Test Coverage](https://api.codeclimate.com/v1/badges/?????/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) +[![Test Coverage](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) [![Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/master/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/master/) -[![Coverage Status](https://coveralls.io/repos/github/reactive-firewall/multicast/badge.svg?branch=master)](https://coveralls.io/github/reactive-firewall/multicast?branch=master) -[![Coverity](https://scan.coverity.com/projects/????/badge.svg)](https://scan.coverity.com/projects/reactive-firewall-multicast) -[![Code Climate](https://codeclimate.com/github/reactive-firewall/multicast/badges/gpa.svg)](https://codeclimate.com/github/reactive-firewall/multicast) +[![Code Climate](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/maintainability)](https://codeclimate.com/github/reactive-firewall/multicast) [![CodeFactor](https://www.codefactor.io/repository/github/reactive-firewall/multicast/badge)](https://www.codefactor.io/repository/github/reactive-firewall/multicast) [![Codebeat badge](https://codebeat.co/badges/?????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-master) ![Size](https://img.shields.io/github/languages/code-size/reactive-firewall/multicast.svg) @@ -28,7 +26,6 @@ Continuous integration testing is handeled by Circle-CI Service. [![Stable-CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/stable.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/stable) [![Atable-Appveyor](https://ci.appveyor.com/api/projects/status/????/branch/stable?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/stable) [![stable-code-coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/) -[![Stable Coverage Status](https://coveralls.io/repos/github/reactive-firewall/multicast/badge.svg?branch=stable)](https://coveralls.io/github/reactive-firewall/multicast?branch=stable) [![Staqble Codebeat Badge](https://codebeat.co/badges/????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-stable) # How do I get this running? From 3d8366e7a32f7e4725a08c1c12fd402426d71a10 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 22:16:26 -0800 Subject: [PATCH 004/135] [TESTS] Numerous fixes for CI testing --- .codecov.yml | 2 +- .github/workflows/Tests.yml | 23 ++++-- README.md | 1 + tests/check_codecov | 138 ++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 5 deletions(-) create mode 100755 tests/check_codecov diff --git a/.codecov.yml b/.codecov.yml index 2e91d53b..7e5bf3b1 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -11,7 +11,7 @@ coverage: - tests flags: - tests: + unittests: paths: - tests joined: false diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 2331fca7..486a530f 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -1,5 +1,5 @@ name: CI -on: [push] +on: [push,pull-request] jobs: MATS: @@ -22,15 +22,19 @@ jobs: run: | echo Testing M.A.T.s, make -j1 -f Makefile test || true + - name: Generate coverage report + run: | + coverage combine || coverage3 combine + coverage xml || coverage3 xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: - directory: ./coverage/reports/ + token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS,PYTHON fail_ci_if_error: true - files: ./coverage1.xml,./coverage2.xml + files: ./coverage.xml flags: unittests - name: codecov-umbrella + name: codecov-github-action path_to_write_report: ./coverage/codecov_report.txt verbose: true - name: Post-Clean @@ -40,8 +44,19 @@ jobs: runs-on: ubuntu-latest + env: + PYTHON: '3.9' + steps: - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: 3.9 + - name: Generate coverage report + run: | + echo Setup linters, + pip install -e ./requirements.txt - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests diff --git a/README.md b/README.md index e9e6eee3..9273788c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Continuous integration testing is handeled by Circle-CI Service. ### master: [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) +[![CI](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml/badge.svg?branch=master)](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml) [![Appveyor](https://ci.appveyor.com/api/projects/status/??????/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) [![Test Coverage](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) [![Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/master/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/master/) diff --git a/tests/check_codecov b/tests/check_codecov new file mode 100755 index 00000000..eac95324 --- /dev/null +++ b/tests/check_codecov @@ -0,0 +1,138 @@ +#! /bin/bash +# Disclaimer of Warranties. +# A. YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT, TO THE EXTENT PERMITTED BY +# APPLICABLE LAW, USE OF THIS SHELL SCRIPT AND ANY SERVICES PERFORMED +# BY OR ACCESSED THROUGH THIS SHELL SCRIPT IS AT YOUR SOLE RISK AND +# THAT THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY AND +# EFFORT IS WITH YOU. +# +# B. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SHELL SCRIPT +# AND SERVICES ARE PROVIDED "AS IS" AND “AS AVAILABLE”, WITH ALL FAULTS AND +# WITHOUT WARRANTY OF ANY KIND, AND THE AUTHOR OF THIS SHELL SCRIPT'S LICENSORS +# (COLLECTIVELY REFERRED TO AS "THE AUTHOR" FOR THE PURPOSES OF THIS DISCLAIMER) +# HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH RESPECT TO THIS SHELL SCRIPT +# SOFTWARE AND SERVICES, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +# NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF +# MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, +# ACCURACY, QUIET ENJOYMENT, AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. +# +# C. THE AUTHOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE +# THE AUTHOR's SOFTWARE AND SERVICES, THAT THE FUNCTIONS CONTAINED IN, OR +# SERVICES PERFORMED OR PROVIDED BY, THIS SHELL SCRIPT WILL MEET YOUR +# REQUIREMENTS, THAT THE OPERATION OF THIS SHELL SCRIPT OR SERVICES WILL +# BE UNINTERRUPTED OR ERROR-FREE, THAT ANY SERVICES WILL CONTINUE TO BE MADE +# AVAILABLE, THAT THIS SHELL SCRIPT OR SERVICES WILL BE COMPATIBLE OR +# WORK WITH ANY THIRD PARTY SOFTWARE, APPLICATIONS OR THIRD PARTY SERVICES, +# OR THAT DEFECTS IN THIS SHELL SCRIPT OR SERVICES WILL BE CORRECTED. +# INSTALLATION OF THIS THE AUTHOR SOFTWARE MAY AFFECT THE USABILITY OF THIRD +# PARTY SOFTWARE, APPLICATIONS OR THIRD PARTY SERVICES. +# +# D. YOU FURTHER ACKNOWLEDGE THAT THIS SHELL SCRIPT AND SERVICES ARE NOT +# INTENDED OR SUITABLE FOR USE IN SITUATIONS OR ENVIRONMENTS WHERE THE FAILURE +# OR TIME DELAYS OF, OR ERRORS OR INACCURACIES IN, THE CONTENT, DATA OR +# INFORMATION PROVIDED BY THIS SHELL SCRIPT OR SERVICES COULD LEAD TO +# DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE, +# INCLUDING WITHOUT LIMITATION THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT +# NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, LIFE SUPPORT OR +# WEAPONS SYSTEMS. +# +# E. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY THE AUTHOR +# SHALL CREATE A WARRANTY. SHOULD THIS SHELL SCRIPT OR SERVICES PROVE DEFECTIVE, +# YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +# +# Limitation of Liability. +# F. TO THE EXTENT NOT PROHIBITED BY APPLICABLE LAW, IN NO EVENT SHALL THE AUTHOR +# BE LIABLE FOR PERSONAL INJURY, OR ANY INCIDENTAL, SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES +# FOR LOSS OF PROFITS, CORRUPTION OR LOSS OF DATA, FAILURE TO TRANSMIT OR +# RECEIVE ANY DATA OR INFORMATION, BUSINESS INTERRUPTION OR ANY OTHER +# COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR +# INABILITY TO USE THIS SHELL SCRIPT OR SERVICES OR ANY THIRD PARTY +# SOFTWARE OR APPLICATIONS IN CONJUNCTION WITH THIS SHELL SCRIPT OR +# SERVICES, HOWEVER CAUSED, REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, +# TORT OR OTHERWISE) AND EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION +# OR LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF INCIDENTAL OR +# CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event +# shall THE AUTHOR's total liability to you for all damages (other than as may +# be required by applicable law in cases involving personal injury) exceed +# the amount of five dollars ($5.00). The foregoing limitations will apply +# even if the above stated remedy fails of its essential purpose. +################################################################################ + +ulimit -t 1200 +PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${PATH}" +umask 027 + +LOCK_FILE="/tmp/codecov_test_script_lock" +EXIT_CODE=0 + +test -x $(command -v grep) || exit 126 ; +test -x $(command -v curl) || exit 126 ; +test -x $(command -v shasum) || exit 126 ; + +function cleanup() { + rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; + rm -f ./codecov 2>/dev/null || true ; wait ; +} + +if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then + trap 'cleanup ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 + trap 'cleanup ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 + trap 'cleanup ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 + trap 'cleanup ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 + trap 'cleanup ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 + trap 'cleanup ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 + trap 'cleanup ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 +else + echo CodeCov already in progress by `head ${LOCK_FILE}` ; + false ; + exit 126 ; +fi + +# this is how test files are found: + +# THIS IS THE ACTUAL TEST +_TEST_ROOT_DIR="./" ; +if [[ -d ./multicast ]] ; then + _TEST_ROOT_DIR="./multicast" ; + _TEST_ROOT_DIR="./" ; +elif [[ -d ./tests ]] ; then + _TEST_ROOT_DIR="./" ; +else + echo "FAIL: missing valid folder or file" + EXIT_CODE=1 +fi + +if [[ ( -r ./codecov_env ) ]] ; then + source ./codecov_env 2>/dev/null || true ; +fi + +# actual Work starts here +curl -fLso codecov https://codecov.io/bash; +VERSION=$(grep -o 'VERSION=\"[0-9\.]*\"' codecov | cut -d'"' -f2); +for i in 1 256 512 ; do + shasum -a $i -c --ignore-missing <(curl -s "https://github.com/raw/codecov/codecov-bash/${VERSION}/SHA${i}SUM") || EXIT_CODE=126 +done + +if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then + chmod -v 751 ./codecov +fi + +if [[ ( -x $(command -v coverage3) ) ]] ; then + coverage3 combine 2>/dev/null || true + coverage3 xml 2>/dev/null || true +elif [[ ( -x $(command -v coverage) ) ]] ; then + coverage combine 2>/dev/null || true + coverage xml 2>/dev/null || true +fi + +./codecov -n "Custom Test Run" -X gcov -F unittests -U "--header 'Dnt: 1;'" || EXIT_CODE=5 ; + +unset _TEST_ROOT_DIR 2>/dev/null || true ; + +rm -f ${LOCK_FILE} 2>/dev/null > /dev/null || true ; wait ; +rm -f ./codecov 2>/dev/null > /dev/null || true ; wait ; + +# goodbye +exit ${EXIT_CODE:-255} ; From 98ee8cad94b3a0bd89fb204b7494f3de4d09abee Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 22:21:33 -0800 Subject: [PATCH 005/135] [REGRESSION] regression fix for CI actions --- .github/workflows/Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 486a530f..7e0c3604 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -1,5 +1,5 @@ name: CI -on: [push,pull-request] +on: [push] jobs: MATS: From a8101fb34b783b8dd9ff44914c293368948ed003 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 22:36:10 -0800 Subject: [PATCH 006/135] [TESTS] fixes for fixes of CI testing (unstable) --- .codecov.yml | 2 +- .github/workflows/Tests.yml | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 7e5bf3b1..27a243e7 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -6,7 +6,7 @@ coverage: base: auto tests: target: 80% - flags: tests + flags: unittests paths: - tests diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 7e0c3604..e6e9a517 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -16,6 +16,10 @@ jobs: uses: actions/setup-python@master with: python-version: 3.9 + - name: Setup Linters + run: | + echo Setup linters, + pip install -r ./requirements.txt || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests @@ -35,7 +39,6 @@ jobs: files: ./coverage.xml flags: unittests name: codecov-github-action - path_to_write_report: ./coverage/codecov_report.txt verbose: true - name: Post-Clean run: make -j1 -f Makefile clean || true ; @@ -53,10 +56,10 @@ jobs: uses: actions/setup-python@master with: python-version: 3.9 - - name: Generate coverage report + - name: Setup Linters run: | echo Setup linters, - pip install -e ./requirements.txt + pip install -r ./requirements.txt - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests From 797755cdbf3643cc277a17543cd20886b8f68d56 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 22:43:34 -0800 Subject: [PATCH 007/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index e6e9a517..408a7d1e 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -28,8 +28,9 @@ jobs: make -j1 -f Makefile test || true - name: Generate coverage report run: | - coverage combine || coverage3 combine - coverage xml || coverage3 xml + pip install coverage>=5.0 || true ; + coverage combine || coverage3 combine || python -m coverage combine ; + coverage xml || coverage3 xml || python -m coverage xml ; - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: From 8273bd7aadcffcb03ddd2bae305278167ee80619 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 22:46:40 -0800 Subject: [PATCH 008/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 408a7d1e..deb4291a 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -20,6 +20,7 @@ jobs: run: | echo Setup linters, pip install -r ./requirements.txt || true ; + pip install coverage>=5.0 || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests @@ -28,7 +29,6 @@ jobs: make -j1 -f Makefile test || true - name: Generate coverage report run: | - pip install coverage>=5.0 || true ; coverage combine || coverage3 combine || python -m coverage combine ; coverage xml || coverage3 xml || python -m coverage xml ; - name: Upload coverage to Codecov From 9b87ac6ca71585da0bce788d12e1aaf187b62931 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 23:13:41 -0800 Subject: [PATCH 009/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 49 +++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index deb4291a..7a80706c 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -1,32 +1,47 @@ name: CI on: [push] jobs: - MATS: + BUILD: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Pre-Clean + run: make -j1 -f Makefile clean || true ; + - name: Run Tests + run: | + echo Testing Build, + make -j1 -f Makefile build || true + - name: Post-Clean + run: make -j1 -f Makefile purge || true ; + + MATS: + if: ${{ always() }} + needs: BUILD runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.7, 3.8, 3.9] env: OS: ${{ matrix.os }} - PYTHON: '3.9' + PYTHON: ${{ matrix.python-version }} steps: - uses: actions/checkout@master - name: Setup Python uses: actions/setup-python@master with: - python-version: 3.9 - - name: Setup Linters + python-version: ${{ matrix.python-version }} + - name: Setup Dependencies run: | - echo Setup linters, + echo Setup dependencies, pip install -r ./requirements.txt || true ; pip install coverage>=5.0 || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests - run: | - echo Testing M.A.T.s, - make -j1 -f Makefile test || true + run: make -j1 -f Makefile test ; - name: Generate coverage report run: | coverage combine || coverage3 combine || python -m coverage combine ; @@ -45,7 +60,8 @@ jobs: run: make -j1 -f Makefile clean || true ; STYLE: - + if: ${{ always() }} + needs: [BUILD, MATS] runs-on: ubuntu-latest env: @@ -69,18 +85,3 @@ jobs: make -j1 -f Makefile test-style || true - name: Post-Clean run: make -j1 -f Makefile clean || true ; - - BUILD: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Pre-Clean - run: make -j1 -f Makefile clean || true ; - - name: Run Tests - run: | - echo Testing Build, - make -j1 -f Makefile build || true - - name: Post-Clean - run: make -j1 -f Makefile purge || true ; From d0ba1ca075d95ff1335fd5fc35cb5add7f2bb50e Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 17 Jan 2022 23:44:43 -0800 Subject: [PATCH 010/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 7a80706c..cccd496a 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -30,20 +30,18 @@ jobs: steps: - uses: actions/checkout@master - name: Setup Python - uses: actions/setup-python@master + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Setup Dependencies - run: | + - run: | echo Setup dependencies, - pip install -r ./requirements.txt || true ; - pip install coverage>=5.0 || true ; + pip install -r ./requirements.txt ; + pip install coverage>=5.0 ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests run: make -j1 -f Makefile test ; - - name: Generate coverage report - run: | + - run: | coverage combine || coverage3 combine || python -m coverage combine ; coverage xml || coverage3 xml || python -m coverage xml ; - name: Upload coverage to Codecov @@ -51,6 +49,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS,PYTHON + drirectory: ${{ github.workspace }} fail_ci_if_error: true files: ./coverage.xml flags: unittests From f4074475b822dad540b7f875f77ec14e154cc7b9 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 17:43:39 -0800 Subject: [PATCH 011/135] [FIX] Fix for github infinite loop link warnings --- multicast/.gitattributes | 1 - tests/.gitattributes | 1 - 2 files changed, 2 deletions(-) delete mode 120000 multicast/.gitattributes delete mode 120000 tests/.gitattributes diff --git a/multicast/.gitattributes b/multicast/.gitattributes deleted file mode 120000 index 6b504345..00000000 --- a/multicast/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -../.gitattributes \ No newline at end of file diff --git a/tests/.gitattributes b/tests/.gitattributes deleted file mode 120000 index 6b504345..00000000 --- a/tests/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -../.gitattributes \ No newline at end of file From c67b82d63e8847625ab6d53f9369c2fdf1373d6e Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 18:31:10 -0800 Subject: [PATCH 012/135] [STYLE] Fixes for things --- .appveyor.yml | 4 +++- multicast/.gitattributes | 1 - tests/.gitattributes | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 120000 multicast/.gitattributes delete mode 120000 tests/.gitattributes diff --git a/.appveyor.yml b/.appveyor.yml index 2c046836..f6737f55 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -6,6 +6,8 @@ branches: skip_tags: true max_jobs: 1 image: +- Visual Studio 2022 +- Visual Studio 2019 - Visual Studio 2017 - Visual Studio 2015 clone_depth: 50 @@ -42,7 +44,7 @@ test_script: dir - codecov || VER>NUL + codecov -f coverage.xml || VER>NUL dir diff --git a/multicast/.gitattributes b/multicast/.gitattributes deleted file mode 120000 index 6b504345..00000000 --- a/multicast/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -../.gitattributes \ No newline at end of file diff --git a/tests/.gitattributes b/tests/.gitattributes deleted file mode 120000 index 6b504345..00000000 --- a/tests/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -../.gitattributes \ No newline at end of file From f2b09dc12b33be04d4fdbd4c7d3f50b19ad5ac48 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 18:44:06 -0800 Subject: [PATCH 013/135] [STYLE] Fixes for things --- .appveyor.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index f6737f55..f5e38c29 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -9,7 +9,6 @@ image: - Visual Studio 2022 - Visual Studio 2019 - Visual Studio 2017 -- Visual Studio 2015 clone_depth: 50 init: - cmd: >- @@ -21,9 +20,9 @@ init: choco upgrade python --pre || VER>NUL - python -m pip install flake8 || VER>NUL + python3 -m pip install flake8 || VER>NUL - python -m pip install coverage || VER>NUL + python3 -m pip install coverage || VER>NUL choco install codecov || VER>NUL From 81d2f49d0bbcf3d515457718e4ab4fc6ba7e9540 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 18:50:08 -0800 Subject: [PATCH 014/135] [STYLE] Fixes for Circle-CI --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b4b66c8..b1b12fbe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - - image: circleci/python:3.9 + - image: circleci/python:3.9 environment: CI: cicleci DEBIAN_FRONTEND: noninteractive @@ -45,7 +45,7 @@ jobs: - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - - image: circleci/python:3.9 + - image: circleci/python:3.9 parallelism: 2 environment: CI: cicleci @@ -99,7 +99,7 @@ jobs: - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - - image: circleci/python:3.9 + - image: circleci/python:3.9 parallelism: 2 environment: CI: cicleci From 1f9d970281eb2e694ddde8acf55b0e100858e183 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 19:18:56 -0800 Subject: [PATCH 015/135] [TESTS] Fixes for Github Actions --- .github/workflows/Tests.yml | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index cccd496a..ef1da8b6 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -16,9 +16,8 @@ jobs: - name: Post-Clean run: make -j1 -f Makefile purge || true ; - MATS: + COVERAGE: if: ${{ always() }} - needs: BUILD runs-on: ${{ matrix.os }} strategy: matrix: @@ -26,7 +25,34 @@ jobs: python-version: [3.7, 3.8, 3.9] env: OS: ${{ matrix.os }} - PYTHON: ${{ matrix.python-version }} + PYTHON_VERSION: ${{ matrix.python-version }} + steps: + - uses: actions/checkout@master + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Setup dependencies + run: | + pip install -r ./requirements.txt ; + pip install coverage>=5.0 || true ; + - name: Pre-Clean + run: make -j1 -f Makefile clean || true ; + - name: Run Tests + run: make -j1 -f Makefile test ; + - name: Post-Clean + run: make -j1 -f Makefile clean || true ; + + COVERAGE: + needs: [BUILD, MATS] + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.7, 3.8, 3.9] + env: + OS: ${{ matrix.os }} + PYTHON_VERSION: ${{ matrix.python-version }} steps: - uses: actions/checkout@master - name: Setup Python @@ -51,10 +77,10 @@ jobs: env_vars: OS,PYTHON drirectory: ${{ github.workspace }} fail_ci_if_error: true - files: ./coverage.xml + files: coverage.xml flags: unittests name: codecov-github-action - verbose: true + verbose: true - name: Post-Clean run: make -j1 -f Makefile clean || true ; From 4a771a128db8dcbf3e74e824e7cb004d16013672 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 19:22:54 -0800 Subject: [PATCH 016/135] [TESTS] Fixes for Github Actions --- .github/workflows/Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index ef1da8b6..d60032bb 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -16,7 +16,7 @@ jobs: - name: Post-Clean run: make -j1 -f Makefile purge || true ; - COVERAGE: + MATS: if: ${{ always() }} runs-on: ${{ matrix.os }} strategy: From 390b82228f4ba1779f0af2ab0a2a2cc752dd0add Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 19:38:19 -0800 Subject: [PATCH 017/135] [TESTS] Improvements for Github Actions --- .github/workflows/Tests.yml | 44 +++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index d60032bb..4c56c15a 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -18,6 +18,7 @@ jobs: MATS: if: ${{ always() }} + needs: BUILD runs-on: ${{ matrix.os }} strategy: matrix: @@ -74,7 +75,7 @@ jobs: uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} - env_vars: OS,PYTHON + env_vars: OS,PYTHON_VERSION drirectory: ${{ github.workspace }} fail_ci_if_error: true files: coverage.xml @@ -90,7 +91,7 @@ jobs: runs-on: ubuntu-latest env: - PYTHON: '3.9' + PYTHON_VERSION: '3.9' steps: - uses: actions/checkout@v2 @@ -100,13 +101,42 @@ jobs: python-version: 3.9 - name: Setup Linters run: | - echo Setup linters, - pip install -r ./requirements.txt + pip install -r ./requirements.txt ; + pip install flake8>=2.5.4 ; + pip install pyflakes>=1.1.0 ; + pip install pep8>=1.7.0 ; + pip install mccab || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - - name: Run Tests + - name: Testing Style + run: make -j1 -f Makefile test-style ; + - name: Post-Clean + run: make -j1 -f Makefile clean || true ; + + TOX: + needs: [MATS, STYLE, COVERAGE] + runs-on: ubuntu-latest + + env: + PYTHON_VERSION: '3.9' + + steps: + - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: 3.9 + - name: install TOX run: | - echo Testing Style, - make -j1 -f Makefile test-style || true + pip install -r ./requirements.txt ; + pip install -U tox>=3.0.0 || true ; + pip install flake8>=2.5.4 || true ; + pip install pyflakes>=1.1.0 || true ; + pip install pep8>=1.7.0 || true ; + pip install mccab || true ; + - name: Pre-Clean + run: make -j1 -f Makefile clean || true ; + - name: Testing Style + run: make -j1 -f Makefile test-tox || true ; - name: Post-Clean run: make -j1 -f Makefile clean || true ; From 0d449c7dac78803474bc358f84b4a1bfd0384601 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 20:15:15 -0800 Subject: [PATCH 018/135] [TESTS] Improvements for Github Actions --- .github/workflows/Labeler.yml | 11 +++++++++++ .github/workflows/Tests.yml | 12 ++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/Labeler.yml diff --git a/.github/workflows/Labeler.yml b/.github/workflows/Labeler.yml new file mode 100644 index 00000000..331ddc9b --- /dev/null +++ b/.github/workflows/Labeler.yml @@ -0,0 +1,11 @@ +name: "Pull Request Labeler" +on: +- pull_request_target + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 4c56c15a..43c16fb3 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -66,17 +66,17 @@ jobs: pip install coverage>=5.0 ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - - name: Run Tests - run: make -j1 -f Makefile test ; - - run: | - coverage combine || coverage3 combine || python -m coverage combine ; - coverage xml || coverage3 xml || python -m coverage xml ; + - name: Generate Coverage + run: | + make -f Makefile test ; wait ; + ls -lap ; + coverage combine || coverage3 combine || python -m coverage combine || true ; wait ; + coverage xml || coverage3 xml || python -m coverage xml || true ; wait ; - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS,PYTHON_VERSION - drirectory: ${{ github.workspace }} fail_ci_if_error: true files: coverage.xml flags: unittests From 6147cbebe71033c2ec7739f6bf821a3473af6b3a Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 20:20:37 -0800 Subject: [PATCH 019/135] [TESTS] Improvements for Github setup Actions --- .github/workflows/Tests.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 43c16fb3..033e5289 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -36,7 +36,7 @@ jobs: - name: Setup dependencies run: | pip install -r ./requirements.txt ; - pip install coverage>=5.0 || true ; + pip install coverage || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Run Tests @@ -63,7 +63,7 @@ jobs: - run: | echo Setup dependencies, pip install -r ./requirements.txt ; - pip install coverage>=5.0 ; + pip install coverage ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Generate Coverage @@ -102,9 +102,9 @@ jobs: - name: Setup Linters run: | pip install -r ./requirements.txt ; - pip install flake8>=2.5.4 ; - pip install pyflakes>=1.1.0 ; - pip install pep8>=1.7.0 ; + pip install flake8 ; + pip install pyflakes ; + pip install pep8 ; pip install mccab || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; @@ -129,10 +129,10 @@ jobs: - name: install TOX run: | pip install -r ./requirements.txt ; - pip install -U tox>=3.0.0 || true ; - pip install flake8>=2.5.4 || true ; - pip install pyflakes>=1.1.0 || true ; - pip install pep8>=1.7.0 || true ; + pip install -U tox || true ; + pip install flake8 || true ; + pip install pyflakes || true ; + pip install pep8 || true ; pip install mccab || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; From 6a0b128d724f1f19fa1cfe1f00c1ab06231d4c10 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 20:35:06 -0800 Subject: [PATCH 020/135] [TESTS] Improvements for Github Actions --- .github/workflows/Tests.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 033e5289..96917b9b 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -52,6 +52,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.7, 3.8, 3.9] env: + CI: 'true' ; OS: ${{ matrix.os }} PYTHON_VERSION: ${{ matrix.python-version }} steps: @@ -67,18 +68,13 @@ jobs: - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Generate Coverage - run: | - make -f Makefile test ; wait ; - ls -lap ; - coverage combine || coverage3 combine || python -m coverage combine || true ; wait ; - coverage xml || coverage3 xml || python -m coverage xml || true ; wait ; + run: make -j1 -f Makefile test ; wait ; - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS,PYTHON_VERSION fail_ci_if_error: true - files: coverage.xml flags: unittests name: codecov-github-action verbose: true @@ -105,7 +101,7 @@ jobs: pip install flake8 ; pip install pyflakes ; pip install pep8 ; - pip install mccab || true ; + pip install mccab 2>/dev/null || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Testing Style @@ -133,7 +129,6 @@ jobs: pip install flake8 || true ; pip install pyflakes || true ; pip install pep8 || true ; - pip install mccab || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Testing Style From 75f7c5342c0617152af861e7bffeeb08d521ea71 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 20:38:12 -0800 Subject: [PATCH 021/135] [TESTS] Improvements for Github Actions --- .github/workflows/Tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 96917b9b..16994f6a 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -52,7 +52,6 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.7, 3.8, 3.9] env: - CI: 'true' ; OS: ${{ matrix.os }} PYTHON_VERSION: ${{ matrix.python-version }} steps: From ce783da0b8d60fe14076750a4e8f851ea66d7d48 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 20:53:35 -0800 Subject: [PATCH 022/135] [TESTS] Improvements for Github Actions --- .github/workflows/Tests.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 16994f6a..21a53193 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -19,13 +19,11 @@ jobs: MATS: if: ${{ always() }} needs: BUILD - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.7, 3.8, 3.9] env: - OS: ${{ matrix.os }} PYTHON_VERSION: ${{ matrix.python-version }} steps: - uses: actions/checkout@master @@ -67,7 +65,10 @@ jobs: - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Generate Coverage - run: make -j1 -f Makefile test ; wait ; + run: | + pip install coverage ; + make -j1 -f Makefile test ; wait ; + coverage xml || true ; - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: @@ -76,6 +77,7 @@ jobs: fail_ci_if_error: true flags: unittests name: codecov-github-action + path_to_write_report: ./coverage/codecov_report.txt verbose: true - name: Post-Clean run: make -j1 -f Makefile clean || true ; From c90df8d0be34dfcd83d7f11e2e56396143798ed1 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 20:58:27 -0800 Subject: [PATCH 023/135] [TESTS] DEBUG for Github Actions --- tests/check_codecov | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check_codecov b/tests/check_codecov index eac95324..9319e3d7 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -127,7 +127,7 @@ elif [[ ( -x $(command -v coverage) ) ]] ; then coverage xml 2>/dev/null || true fi -./codecov -n "Custom Test Run" -X gcov -F unittests -U "--header 'Dnt: 1;'" || EXIT_CODE=5 ; +./codecov -n "Custom Test Run" -X gcov -F unittests -v || EXIT_CODE=5 ; unset _TEST_ROOT_DIR 2>/dev/null || true ; From de016ab5bbfb6e29c34b07f481a0f63d1c5a5485 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 21:01:09 -0800 Subject: [PATCH 024/135] [TESTS] DEBUG for Github Actions --- tests/check_codecov | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check_codecov b/tests/check_codecov index 9319e3d7..d7b36a9c 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -127,7 +127,7 @@ elif [[ ( -x $(command -v coverage) ) ]] ; then coverage xml 2>/dev/null || true fi -./codecov -n "Custom Test Run" -X gcov -F unittests -v || EXIT_CODE=5 ; +./codecov -n "Custom Test Run" -X gcov -F unittests || EXIT_CODE=5 ; unset _TEST_ROOT_DIR 2>/dev/null || true ; From 1359bf21bb6929e0a71b7abd4fb4ab57834e2412 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 21:05:40 -0800 Subject: [PATCH 025/135] [TESTS] DEBUG for Github Actions --- .codecov.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 27a243e7..c4db9989 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -2,9 +2,12 @@ coverage: status: project: default: on - target: 95% base: auto - tests: + multicast: + target: 95% + paths: + - multicast + unittests: target: 80% flags: unittests paths: From 34fb482f16cf452bb40e711cd3fe8987d2490a73 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 21:18:38 -0800 Subject: [PATCH 026/135] [TESTS] DEBUG for codecove.yml --- .codecov.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index c4db9989..3b22e1c3 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -2,11 +2,8 @@ coverage: status: project: default: on - base: auto - multicast: - target: 95% - paths: - - multicast + base: auto + target: 95% unittests: target: 80% flags: unittests From a64fb51783da34539dbed7ed5238baed88f99d64 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 18 Jan 2022 21:28:50 -0800 Subject: [PATCH 027/135] [TESTS] DEBUG for broken codecov action and no coverage in cloud --- .github/workflows/Tests.yml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 21a53193..f0423ee8 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -2,18 +2,21 @@ name: CI on: [push] jobs: BUILD: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@master + - name: python + uses: actions/setup-python@master + with: + python-version: 3.9 - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - - name: Run Tests - run: | - echo Testing Build, - make -j1 -f Makefile build || true + - name: Test Build + id: build + run: make -j1 -f Makefile build || true ; - name: Post-Clean + id: post run: make -j1 -f Makefile purge || true ; MATS: @@ -36,13 +39,17 @@ jobs: pip install -r ./requirements.txt ; pip install coverage || true ; - name: Pre-Clean + id: pre run: make -j1 -f Makefile clean || true ; - name: Run Tests + id: tests run: make -j1 -f Makefile test ; - name: Post-Clean + id: post run: make -j1 -f Makefile clean || true ; COVERAGE: + if: ${{ success() }} needs: [BUILD, MATS] runs-on: ${{ matrix.os }} strategy: @@ -76,9 +83,9 @@ jobs: env_vars: OS,PYTHON_VERSION fail_ci_if_error: true flags: unittests - name: codecov-github-action - path_to_write_report: ./coverage/codecov_report.txt + name: "codecov-github-action" verbose: true + directory: . - name: Post-Clean run: make -j1 -f Makefile clean || true ; From 40d99569b8ddb83d9045c6cc6ce79ae45e3c9470 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 02:59:04 -0800 Subject: [PATCH 028/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index f0423ee8..f02920ae 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -47,6 +47,7 @@ jobs: - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} COVERAGE: if: ${{ success() }} @@ -61,22 +62,22 @@ jobs: PYTHON_VERSION: ${{ matrix.python-version }} steps: - uses: actions/checkout@master - - name: Setup Python + - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - run: | - echo Setup dependencies, + - name: Install dependencies for ${{ matrix.python-version }} + run: | + python -m pip install --upgrade pip setuptools wheel pip install -r ./requirements.txt ; pip install coverage ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Generate Coverage run: | - pip install coverage ; - make -j1 -f Makefile test ; wait ; - coverage xml || true ; - - name: Upload coverage to Codecov + make -f Makefile test ; wait ; + python -m coverage xml || coverage xml || true ; + - name: Upload Python ${{ matrix.python-version }} coverage to Codecov uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -88,6 +89,8 @@ jobs: directory: . - name: Post-Clean run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} + STYLE: if: ${{ always() }} @@ -105,17 +108,18 @@ jobs: python-version: 3.9 - name: Setup Linters run: | + python -m pip install --upgrade pip setuptools wheel pip install -r ./requirements.txt ; pip install flake8 ; pip install pyflakes ; pip install pep8 ; - pip install mccab 2>/dev/null || true ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - name: Testing Style run: make -j1 -f Makefile test-style ; - name: Post-Clean run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} TOX: needs: [MATS, STYLE, COVERAGE] @@ -132,8 +136,8 @@ jobs: python-version: 3.9 - name: install TOX run: | + python -m pip install --upgrade pip setuptools wheel tox pip install -r ./requirements.txt ; - pip install -U tox || true ; pip install flake8 || true ; pip install pyflakes || true ; pip install pep8 || true ; @@ -143,3 +147,4 @@ jobs: run: make -j1 -f Makefile test-tox || true ; - name: Post-Clean run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} From e177415a326ce067274a746dda76782cefb55f77 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 03:36:44 -0800 Subject: [PATCH 029/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index f02920ae..b302c924 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -73,10 +73,10 @@ jobs: pip install coverage ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - - name: Generate Coverage - run: | - make -f Makefile test ; wait ; - python -m coverage xml || coverage xml || true ; + - run: command -v coverage || true + - run: command -v coverage3 || true + - name: Generate Coverage for py${{ matrix.python-version }} + run: make -j1 -f Makefile test ; wait ; - name: Upload Python ${{ matrix.python-version }} coverage to Codecov uses: codecov/codecov-action@v2 with: From 5e74d4714cf4c7cbd5b99f8d08ba243fdcb9db11 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 03:41:19 -0800 Subject: [PATCH 030/135] [TESTS] CI testing (unstable) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1fe2a830..5898c62c 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ifeq "$(PYTHON)" "" endif ifeq "$(COVERAGE)" "" - ifeq "$(PYTHON)" "" + ifeq "$(COVERAGE)" "" COVERAGE=$(command -v coverage) endif ifeq "$(COVERAGE)" "" From f2340f952e5771402e31e97d258e33be12b8a49c Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 04:10:19 -0800 Subject: [PATCH 031/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 5 +++++ Makefile | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index b302c924..cfbe41f6 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -3,6 +3,8 @@ on: [push] jobs: BUILD: runs-on: ubuntu-latest + env: + LANG: "en_US.UTF-8" steps: - uses: actions/checkout@master - name: python @@ -28,6 +30,7 @@ jobs: python-version: [3.7, 3.8, 3.9] env: PYTHON_VERSION: ${{ matrix.python-version }} + LANG: "en_US.UTF-8" steps: - uses: actions/checkout@master - name: Setup Python @@ -60,6 +63,7 @@ jobs: env: OS: ${{ matrix.os }} PYTHON_VERSION: ${{ matrix.python-version }} + LANG: "en_US.UTF-8" steps: - uses: actions/checkout@master - name: Setup Python ${{ matrix.python-version }} @@ -99,6 +103,7 @@ jobs: env: PYTHON_VERSION: '3.9' + LANG: "en_US.UTF-8" steps: - uses: actions/checkout@v2 diff --git a/Makefile b/Makefile index 5898c62c..b70b314a 100644 --- a/Makefile +++ b/Makefile @@ -99,7 +99,9 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose -s ./tests -t ./ || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)echo $(COVERAGE) ; + ##$(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose -s ./tests -t ./ || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)$(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); From c69a192bcc9bf0d308aa7ef62523661a6c5e5708 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 04:15:43 -0800 Subject: [PATCH 032/135] [TESTS] CI testing (unstable) --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index b70b314a..6e86f37b 100644 --- a/Makefile +++ b/Makefile @@ -99,9 +99,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)echo $(COVERAGE) ; - ##$(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose -s ./tests -t ./ || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; - $(QUIET)$(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); From 3c96c8dfeb4dec5d382fd3cd1b8ae04b7b2e8138 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 19:17:36 -0800 Subject: [PATCH 033/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index cfbe41f6..1493b705 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -75,12 +75,13 @@ jobs: python -m pip install --upgrade pip setuptools wheel pip install -r ./requirements.txt ; pip install coverage ; + pip install pytest ; + pip install pytest-cov + pip install coverage ; - name: Pre-Clean run: make -j1 -f Makefile clean || true ; - - run: command -v coverage || true - - run: command -v coverage3 || true - name: Generate Coverage for py${{ matrix.python-version }} - run: make -j1 -f Makefile test ; wait ; + run: make -j1 -f Makefile test-pytest ; wait ; - name: Upload Python ${{ matrix.python-version }} coverage to Codecov uses: codecov/codecov-action@v2 with: From d79640fc85d17e8bf4896c97d8bb5b3c0d6b6f58 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 19:33:43 -0800 Subject: [PATCH 034/135] [TESTS] CI testing (unstable) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6e86f37b..a445270c 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,7 @@ test-tox: cleanup $(QUIET)$(ECHO) "$@: Done." test-pytest: cleanup test-reports - $(QUIET)$(PYTHON) -m pytest --junitxml=test-reports/junit.xml -v tests || python -m pytest --junitxml=test-reports/junit.xml -v tests + $(QUIET)$(PYTHON) -m pytest --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests || python -m pytest --junitxml=test-reports/junit.xml -v tests $(QUIET)$(ECHO) "$@: Done." test-style: cleanup From 2010874c0da927082dc782d191dcab924a998ea3 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 21:01:02 -0800 Subject: [PATCH 035/135] [TESTS] CI testing --- .github/workflows/Tests.yml | 18 ++++++++++++++---- tests/check_codecov | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 1493b705..a30f586d 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.6, 3.7, 3.8, 3.9] env: PYTHON_VERSION: ${{ matrix.python-version }} LANG: "en_US.UTF-8" @@ -42,7 +42,7 @@ jobs: pip install -r ./requirements.txt ; pip install coverage || true ; - name: Pre-Clean - id: pre + id: clean run: make -j1 -f Makefile clean || true ; - name: Run Tests id: tests @@ -79,20 +79,24 @@ jobs: pip install pytest-cov pip install coverage ; - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - name: Generate Coverage for py${{ matrix.python-version }} + id: test-coverage run: make -j1 -f Makefile test-pytest ; wait ; - name: Upload Python ${{ matrix.python-version }} coverage to Codecov uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS,PYTHON_VERSION - fail_ci_if_error: true + fail_ci_if_error: false flags: unittests name: "codecov-github-action" verbose: true directory: . + files: ./coverage.xml - name: Post-Clean + id: post run: make -j1 -f Makefile clean || true ; if: ${{ always() }} @@ -120,10 +124,13 @@ jobs: pip install pyflakes ; pip install pep8 ; - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - name: Testing Style + id: style run: make -j1 -f Makefile test-style ; - name: Post-Clean + id: post run: make -j1 -f Makefile clean || true ; if: ${{ always() }} @@ -144,13 +151,16 @@ jobs: run: | python -m pip install --upgrade pip setuptools wheel tox pip install -r ./requirements.txt ; + pip install coverage || true ; pip install flake8 || true ; pip install pyflakes || true ; pip install pep8 || true ; - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - - name: Testing Style + - name: Testing Tox run: make -j1 -f Makefile test-tox || true ; - name: Post-Clean + id: post run: make -j1 -f Makefile clean || true ; if: ${{ always() }} diff --git a/tests/check_codecov b/tests/check_codecov index d7b36a9c..f8572797 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -62,6 +62,7 @@ ulimit -t 1200 PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${PATH}" +LC_ALL="${LANG:1:5}.utf-8" umask 027 LOCK_FILE="/tmp/codecov_test_script_lock" @@ -92,7 +93,7 @@ fi # this is how test files are found: -# THIS IS THE ACTUAL TEST +# THIS IS THE ACTUAL TEST DIR USED (update _TEST_ROOT_DIR as needed) _TEST_ROOT_DIR="./" ; if [[ -d ./multicast ]] ; then _TEST_ROOT_DIR="./multicast" ; @@ -104,15 +105,38 @@ else EXIT_CODE=1 fi +# This File MUST BE GIT-IGNORED to be SAFELY USED to store Tokens and env vars (update logic as needed) if [[ ( -r ./codecov_env ) ]] ; then source ./codecov_env 2>/dev/null || true ; fi +# sorry no windows support here +if [[ $( \uname -s ) == "Darwin" ]] ; then + CI_OS="macos" +else + CI_OS="linux" +fi + +######################### # actual Work starts here -curl -fLso codecov https://codecov.io/bash; -VERSION=$(grep -o 'VERSION=\"[0-9\.]*\"' codecov | cut -d'"' -f2); +######################### +curl -fLso codecov https://uploader.codecov.io/latest/${CI_OS:-linux}/codecov ; for i in 1 256 512 ; do - shasum -a $i -c --ignore-missing <(curl -s "https://github.com/raw/codecov/codecov-bash/${VERSION}/SHA${i}SUM") || EXIT_CODE=126 + curl -fLso codecov.SHA${i}SUM "https://uploader.codecov.io/latest/${CI_OS:-linux}/codecov.SHA${i}SUM" ; wait ; + curl -fLso codecov.SHA${i}SUM.sig "https://uploader.codecov.io/latest/${CI_OS:-linux}/codecov.SHA${i}SUM.sig" ; wait ; + # test sha1/sha512 signatures if found and sha256 even if not found + if [[ ( -r codecov.SHA${i}SUM ) ]] || [[ ( ${i} -eq 256 ) ]] ; then + if [[ ( -r codecov.SHA${i}SUM.sig ) ]] ; then + # configure your CI evironment to trust the key at https://keybase.io/codecovsecurity/pgp_keys.asc + # FP: 2703 4E7F DB85 0E0B BC2C 62FF 806B B28A ED77 9869 + # OR... + # Set CI=true to continue on missing keys + gpgv codecov.SHA${i}SUM.sig codecov.SHA${i}SUM || ${CI} || EXIT_CODE=126 + rm -vf codecov.SHA${i}SUM.sig 2>/dev/null ; + fi + shasum -a $i -c --ignore-missing codecov.SHA${i}SUM || EXIT_CODE=126 + rm -vf codecov.SHA${i}SUM 2>/dev/null ; + fi done if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then @@ -127,7 +151,10 @@ elif [[ ( -x $(command -v coverage) ) ]] ; then coverage xml 2>/dev/null || true fi -./codecov -n "Custom Test Run" -X gcov -F unittests || EXIT_CODE=5 ; +if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then + ./codecov -n "Custom Test Run" -X gcov -F unittests || EXIT_CODE=5 ; +fi + unset _TEST_ROOT_DIR 2>/dev/null || true ; From fd8772ec0291515be48a52b40216d92b1f6c0f31 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 21:13:18 -0800 Subject: [PATCH 036/135] [BREAKS] EOL python 2.x --- .github/workflows/Tests.yml | 2 +- Makefile | 5 +++-- setup.cfg | 6 ++---- setup.py | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index a30f586d..81827baf 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: [3.7, 3.8, 3.9] env: PYTHON_VERSION: ${{ matrix.python-version }} LANG: "en_US.UTF-8" diff --git a/Makefile b/Makefile index a445270c..76a87956 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,7 @@ init: $(QUIET)$(ECHO) "$@: Done." install: must_be_root + $(QUIET)$(PYTHON) -m pip install --upgrade pip setuptools wheel || true $(QUIET)$(PYTHON) -m pip install "git+https://github.com/reactive-firewall/multicast.git#egg=multicast" $(QUITE)$(WAIT) $(QUIET)$(ECHO) "$@: Done." @@ -99,7 +100,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)$(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); @@ -110,7 +111,7 @@ test-tox: cleanup $(QUIET)$(ECHO) "$@: Done." test-pytest: cleanup test-reports - $(QUIET)$(PYTHON) -m pytest --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests || python -m pytest --junitxml=test-reports/junit.xml -v tests + $(QUIET)$(PYTHON) -m pytest --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests $(QUIET)$(ECHO) "$@: Done." test-style: cleanup diff --git a/setup.cfg b/setup.cfg index 544bf3ad..9cc0f530 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,8 +19,6 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.5 [bdist_rpm] url = https://www.github.com/reactive-firewall/multicast.git @@ -32,8 +30,8 @@ universal=1 packages = multicast [options] -py_modules = piaplib -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +py_modules = multicast +python_requires = >=3.7 packages = find:*.py scripts = multicast/__main__.py diff --git a/setup.py b/setup.py index 7add32d6..db19b9d2 100755 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # .......................................... -# http://www.github.com/reactive-firewall/multicast/LICENSE.md +# http://www.github.com/reactive-firewall/multicast/LICENSE # .......................................... # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, From e8a09845c2a2d7d1c4c4444a643e1462d6525aec Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 19 Jan 2022 21:36:49 -0800 Subject: [PATCH 037/135] [TESTS] CI testing (unstable) --- .github/workflows/Tests.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 81827baf..c4ab48c0 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -82,19 +82,17 @@ jobs: id: clean run: make -j1 -f Makefile clean || true ; - name: Generate Coverage for py${{ matrix.python-version }} - id: test-coverage - run: make -j1 -f Makefile test-pytest ; wait ; + run: make -j1 -f Makefile test-pytest ; - name: Upload Python ${{ matrix.python-version }} coverage to Codecov uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} - env_vars: OS,PYTHON_VERSION - fail_ci_if_error: false - flags: unittests - name: "codecov-github-action" - verbose: true - directory: . files: ./coverage.xml + directory: . + flags: unittests,${{ matrix.os }},${{ matrix.python-version }} + name: multicast-github-${{ matrix.os }}-${{ matrix.python-version }} + verbose: true + fail_ci_if_error: true - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; From 594ea7b10f5a552784ecac2e67006dbcea988bce Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 03:06:09 -0800 Subject: [PATCH 038/135] [TESTS] CI testing (unstable) --- tests/check_codecov | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/check_codecov b/tests/check_codecov index f8572797..9994ffdb 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -110,6 +110,13 @@ if [[ ( -r ./codecov_env ) ]] ; then source ./codecov_env 2>/dev/null || true ; fi +if [[ ( -r ./codecov.yml ) ]] ; then + cat codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 +fi +if [[ ( -r ./.codecov.yml ) ]] ; then + cat ./.codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 +fi + # sorry no windows support here if [[ $( \uname -s ) == "Darwin" ]] ; then CI_OS="macos" @@ -140,7 +147,7 @@ for i in 1 256 512 ; do done if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then - chmod -v 751 ./codecov + chmod -v 751 ./codecov || EXIT_CODE=126 fi if [[ ( -x $(command -v coverage3) ) ]] ; then From 07292c235e1fa42fe52f5d04d26cf0be66e789f0 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 03:15:28 -0800 Subject: [PATCH 039/135] [TESTS] CI testing (unstable) --- .codecov.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 3b22e1c3..e77cfc5e 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -2,16 +2,17 @@ coverage: status: project: default: on - base: auto target: 95% + threshold: 0% + base: auto unittests: target: 80% flags: unittests paths: - - tests + - "tests/*" flags: unittests: paths: - - tests + - "tests/*" joined: false From 3f5a362d4cc3a1ef2ed160b6bf1abfea6c7907ca Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 03:32:25 -0800 Subject: [PATCH 040/135] [TESTS] CI testing (unstable) --- .codecov.yml | 25 ++++++++++++++++++++----- tests/check_codecov | 4 ++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index e77cfc5e..ede9b74e 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,13 +1,21 @@ coverage: status: project: - default: on - target: 95% - threshold: 0% - base: auto + default: + target: 95% + threshold: 0% + base: auto + multicast: + target: auto + flags: + - multicast + paths: + - "multicast/*.py" + - "setup.py" unittests: target: 80% - flags: unittests + flags: + - unittests paths: - "tests/*" @@ -15,4 +23,11 @@ flags: unittests: paths: - "tests/*" + carryforward: true + joined: false + multicast: + paths: + - "multicast/*.py" + - "setup.py" joined: false + carryforward: true diff --git a/tests/check_codecov b/tests/check_codecov index 9994ffdb..bef6d31d 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -111,10 +111,10 @@ if [[ ( -r ./codecov_env ) ]] ; then fi if [[ ( -r ./codecov.yml ) ]] ; then - cat codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 + cat codecov.yml | curl -X POST --data-binary @- https://codecov.io/validate || EXIT_CODE=6 fi if [[ ( -r ./.codecov.yml ) ]] ; then - cat ./.codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 + cat ./.codecov.yml | curl -X POST --data-binary @- https://codecov.io/validate || EXIT_CODE=6 fi # sorry no windows support here From fa8fd7dadb15c738fde0ae7f7881cb27fd41a816 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 04:31:41 -0800 Subject: [PATCH 041/135] [TESTS] CI testing ( PR#10 ) --- .circleci/config.yml | 16 ++++++++-------- .codecov.yml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b1b12fbe..987c4eb0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,9 +10,9 @@ jobs: CI: cicleci DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 - LC_CTYPE: en_EN.UTF-8 + LC_CTYPE: en_US.UTF-8 SHELL: /bin/bash - working_directory: ~/python-repo + working_directory: ~/multicast steps: - checkout - run: @@ -51,9 +51,9 @@ jobs: CI: cicleci DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 - LC_CTYPE: en_EN.UTF-8 + LC_CTYPE: en_US.UTF-8 SHELL: /bin/bash - working_directory: ~/python-repo + working_directory: ~/multicast steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} @@ -105,9 +105,9 @@ jobs: CI: cicleci DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 - LC_CTYPE: en_EN.UTF-8 + LC_CTYPE: en_US.UTF-8 SHELL: /bin/bash - working_directory: ~/python-repo + working_directory: ~/multicast steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} @@ -162,8 +162,8 @@ jobs: DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 SHELL: /bin/bash - LC_CTYPE: en_EN.UTF-8 - working_directory: ~/python-repo + LC_CTYPE: en_US.UTF-8 + working_directory: ~/multicast steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} diff --git a/.codecov.yml b/.codecov.yml index ede9b74e..17559e82 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -4,7 +4,7 @@ coverage: default: target: 95% threshold: 0% - base: auto + base: auto multicast: target: auto flags: From 63fc3ce48dc62c53b9c2390ddfe68f0ce5331046 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 04:40:32 -0800 Subject: [PATCH 042/135] [TESTS] CI testing ( PR#10 ) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 987c4eb0..1c63c00b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,7 +38,7 @@ jobs: - save_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} paths: - - ~/python-repo + - ~/multicast test: docker: From fcf1015551607471f47a61f0d878e51ca41b6da3 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 04:50:33 -0800 Subject: [PATCH 043/135] [TESTS] CI testing ( PR#10 ) --- .circleci/config.yml | 9 ++++++--- tests/check_codecov | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c63c00b..77112264 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,6 @@ version: 2 jobs: build: docker: - - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - image: circleci/python:3.9 @@ -42,7 +41,6 @@ jobs: test: docker: - - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - image: circleci/python:3.9 @@ -96,7 +94,6 @@ jobs: pytest: docker: - - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - image: circleci/python:3.9 @@ -123,6 +120,12 @@ jobs: command: | python3 -m pip install --user pytest || true when: on_success + - run: + shell: /bin/bash + name: "setup up for pytest" + command: | + python3 -m pip install --user pytest-cov || true + when: on_success - run: shell: /bin/bash name: "clean up for pytest" diff --git a/tests/check_codecov b/tests/check_codecov index bef6d31d..9994ffdb 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -111,10 +111,10 @@ if [[ ( -r ./codecov_env ) ]] ; then fi if [[ ( -r ./codecov.yml ) ]] ; then - cat codecov.yml | curl -X POST --data-binary @- https://codecov.io/validate || EXIT_CODE=6 + cat codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 fi if [[ ( -r ./.codecov.yml ) ]] ; then - cat ./.codecov.yml | curl -X POST --data-binary @- https://codecov.io/validate || EXIT_CODE=6 + cat ./.codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 fi # sorry no windows support here From 0a935125e7a6327652814090226b29f313cb12c7 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 05:01:45 -0800 Subject: [PATCH 044/135] [TESTS] CI testing ( PR#10 ) --- .github/workflows/labler.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/workflows/labler.yml diff --git a/.github/workflows/labler.yml b/.github/workflows/labler.yml deleted file mode 100644 index 47716d46..00000000 --- a/.github/workflows/labler.yml +++ /dev/null @@ -1,17 +0,0 @@ -# This workflow will triage pull requests and apply a label based on the -# paths that are modified in the pull request. -# -# To use this workflow, you will need to set up a .github/labeler.yml -# file with configuration. For more information, see: -# https://github.com/actions/labeler/blob/master/README.md - -name: "Pull Request Labeler" -on: [pull_request] - -jobs: - label: - runs-on: ubuntu-latest - steps: - - uses: actions/labeler@v2 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file From c92dd00df63703f3018d44d5d46a29fb89acd601 Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Thu, 20 Jan 2022 05:24:12 -0800 Subject: [PATCH 045/135] Ci re work #3 (#10) [MERGE] Closes #4 * [STYLE] Added corrected Code Climate Badges to readme * [TESTS] Numerous fixes for CI testing * [REGRESSION] regression fix for CI actions * [STYLE] Fixes for Circle-CI * [TESTS] Fixes for Github Actions * [TESTS] fixes for fixes of CI testing * [BREAKS] EOL python 2.x * [TESTS] CI testing ( PR#10 ) --- .appveyor.yml | 9 +- .circleci/config.yml | 33 ++++--- .codecov.yml | 28 ++++-- .github/workflows/Labeler.yml | 11 +++ .github/workflows/Tests.yml | 153 ++++++++++++++++++++++++------ .github/workflows/labler.yml | 17 ---- Makefile | 7 +- README.md | 1 + setup.cfg | 6 +- setup.py | 2 +- tests/check_codecov | 172 ++++++++++++++++++++++++++++++++++ 11 files changed, 361 insertions(+), 78 deletions(-) create mode 100644 .github/workflows/Labeler.yml delete mode 100644 .github/workflows/labler.yml create mode 100755 tests/check_codecov diff --git a/.appveyor.yml b/.appveyor.yml index 2c046836..f5e38c29 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -6,8 +6,9 @@ branches: skip_tags: true max_jobs: 1 image: +- Visual Studio 2022 +- Visual Studio 2019 - Visual Studio 2017 -- Visual Studio 2015 clone_depth: 50 init: - cmd: >- @@ -19,9 +20,9 @@ init: choco upgrade python --pre || VER>NUL - python -m pip install flake8 || VER>NUL + python3 -m pip install flake8 || VER>NUL - python -m pip install coverage || VER>NUL + python3 -m pip install coverage || VER>NUL choco install codecov || VER>NUL @@ -42,7 +43,7 @@ test_script: dir - codecov || VER>NUL + codecov -f coverage.xml || VER>NUL dir diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b4b66c8..77112264 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,17 +2,16 @@ version: 2 jobs: build: docker: - - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - - image: circleci/python:3.9 + - image: circleci/python:3.9 environment: CI: cicleci DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 - LC_CTYPE: en_EN.UTF-8 + LC_CTYPE: en_US.UTF-8 SHELL: /bin/bash - working_directory: ~/python-repo + working_directory: ~/multicast steps: - checkout - run: @@ -38,22 +37,21 @@ jobs: - save_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} paths: - - ~/python-repo + - ~/multicast test: docker: - - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - - image: circleci/python:3.9 + - image: circleci/python:3.9 parallelism: 2 environment: CI: cicleci DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 - LC_CTYPE: en_EN.UTF-8 + LC_CTYPE: en_US.UTF-8 SHELL: /bin/bash - working_directory: ~/python-repo + working_directory: ~/multicast steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} @@ -96,18 +94,17 @@ jobs: pytest: docker: - - image: circleci/python:3.6.1 - image: circleci/python:3.7 - image: circleci/python:3.8 - - image: circleci/python:3.9 + - image: circleci/python:3.9 parallelism: 2 environment: CI: cicleci DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 - LC_CTYPE: en_EN.UTF-8 + LC_CTYPE: en_US.UTF-8 SHELL: /bin/bash - working_directory: ~/python-repo + working_directory: ~/multicast steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} @@ -123,6 +120,12 @@ jobs: command: | python3 -m pip install --user pytest || true when: on_success + - run: + shell: /bin/bash + name: "setup up for pytest" + command: | + python3 -m pip install --user pytest-cov || true + when: on_success - run: shell: /bin/bash name: "clean up for pytest" @@ -162,8 +165,8 @@ jobs: DEBIAN_FRONTEND: noninteractive LANG: en_US.UTF-8 SHELL: /bin/bash - LC_CTYPE: en_EN.UTF-8 - working_directory: ~/python-repo + LC_CTYPE: en_US.UTF-8 + working_directory: ~/multicast steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} diff --git a/.codecov.yml b/.codecov.yml index 2e91d53b..17559e82 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,17 +1,33 @@ coverage: status: project: - default: on + default: target: 95% + threshold: 0% base: auto - tests: + multicast: + target: auto + flags: + - multicast + paths: + - "multicast/*.py" + - "setup.py" + unittests: target: 80% - flags: tests + flags: + - unittests paths: - - tests + - "tests/*" flags: - tests: + unittests: + paths: + - "tests/*" + carryforward: true + joined: false + multicast: paths: - - tests + - "multicast/*.py" + - "setup.py" joined: false + carryforward: true diff --git a/.github/workflows/Labeler.yml b/.github/workflows/Labeler.yml new file mode 100644 index 00000000..331ddc9b --- /dev/null +++ b/.github/workflows/Labeler.yml @@ -0,0 +1,11 @@ +name: "Pull Request Labeler" +on: +- pull_request_target + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 2331fca7..c4ab48c0 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -1,67 +1,164 @@ name: CI on: [push] jobs: + BUILD: + runs-on: ubuntu-latest + env: + LANG: "en_US.UTF-8" + steps: + - uses: actions/checkout@master + - name: python + uses: actions/setup-python@master + with: + python-version: 3.9 + - name: Pre-Clean + id: clean + run: make -j1 -f Makefile clean || true ; + - name: Test Build + id: build + run: make -j1 -f Makefile build || true ; + - name: Post-Clean + id: post + run: make -j1 -f Makefile purge || true ; + MATS: + if: ${{ always() }} + needs: BUILD + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.7, 3.8, 3.9] + env: + PYTHON_VERSION: ${{ matrix.python-version }} + LANG: "en_US.UTF-8" + steps: + - uses: actions/checkout@master + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Setup dependencies + run: | + pip install -r ./requirements.txt ; + pip install coverage || true ; + - name: Pre-Clean + id: clean + run: make -j1 -f Makefile clean || true ; + - name: Run Tests + id: tests + run: make -j1 -f Makefile test ; + - name: Post-Clean + id: post + run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} + COVERAGE: + if: ${{ success() }} + needs: [BUILD, MATS] runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.7, 3.8, 3.9] env: OS: ${{ matrix.os }} - PYTHON: '3.9' + PYTHON_VERSION: ${{ matrix.python-version }} + LANG: "en_US.UTF-8" steps: - uses: actions/checkout@master - - name: Setup Python - uses: actions/setup-python@master + - name: Setup Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: ${{ matrix.python-version }} + - name: Install dependencies for ${{ matrix.python-version }} + run: | + python -m pip install --upgrade pip setuptools wheel + pip install -r ./requirements.txt ; + pip install coverage ; + pip install pytest ; + pip install pytest-cov + pip install coverage ; - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - - name: Run Tests - run: | - echo Testing M.A.T.s, - make -j1 -f Makefile test || true - - name: Upload coverage to Codecov + - name: Generate Coverage for py${{ matrix.python-version }} + run: make -j1 -f Makefile test-pytest ; + - name: Upload Python ${{ matrix.python-version }} coverage to Codecov uses: codecov/codecov-action@v2 with: - directory: ./coverage/reports/ - env_vars: OS,PYTHON + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage.xml + directory: . + flags: unittests,${{ matrix.os }},${{ matrix.python-version }} + name: multicast-github-${{ matrix.os }}-${{ matrix.python-version }} + verbose: true fail_ci_if_error: true - files: ./coverage1.xml,./coverage2.xml - flags: unittests - name: codecov-umbrella - path_to_write_report: ./coverage/codecov_report.txt - verbose: true - name: Post-Clean + id: post run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} - STYLE: + STYLE: + if: ${{ always() }} + needs: [BUILD, MATS] runs-on: ubuntu-latest + env: + PYTHON_VERSION: '3.9' + LANG: "en_US.UTF-8" + steps: - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: 3.9 + - name: Setup Linters + run: | + python -m pip install --upgrade pip setuptools wheel + pip install -r ./requirements.txt ; + pip install flake8 ; + pip install pyflakes ; + pip install pep8 ; - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - - name: Run Tests - run: | - echo Testing Style, - make -j1 -f Makefile test-style || true + - name: Testing Style + id: style + run: make -j1 -f Makefile test-style ; - name: Post-Clean + id: post run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} - BUILD: - + TOX: + needs: [MATS, STYLE, COVERAGE] runs-on: ubuntu-latest + env: + PYTHON_VERSION: '3.9' + steps: - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: 3.9 + - name: install TOX + run: | + python -m pip install --upgrade pip setuptools wheel tox + pip install -r ./requirements.txt ; + pip install coverage || true ; + pip install flake8 || true ; + pip install pyflakes || true ; + pip install pep8 || true ; - name: Pre-Clean + id: clean run: make -j1 -f Makefile clean || true ; - - name: Run Tests - run: | - echo Testing Build, - make -j1 -f Makefile build || true + - name: Testing Tox + run: make -j1 -f Makefile test-tox || true ; - name: Post-Clean - run: make -j1 -f Makefile purge || true ; + id: post + run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} diff --git a/.github/workflows/labler.yml b/.github/workflows/labler.yml deleted file mode 100644 index 47716d46..00000000 --- a/.github/workflows/labler.yml +++ /dev/null @@ -1,17 +0,0 @@ -# This workflow will triage pull requests and apply a label based on the -# paths that are modified in the pull request. -# -# To use this workflow, you will need to set up a .github/labeler.yml -# file with configuration. For more information, see: -# https://github.com/actions/labeler/blob/master/README.md - -name: "Pull Request Labeler" -on: [pull_request] - -jobs: - label: - runs-on: ubuntu-latest - steps: - - uses: actions/labeler@v2 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file diff --git a/Makefile b/Makefile index 1fe2a830..76a87956 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ifeq "$(PYTHON)" "" endif ifeq "$(COVERAGE)" "" - ifeq "$(PYTHON)" "" + ifeq "$(COVERAGE)" "" COVERAGE=$(command -v coverage) endif ifeq "$(COVERAGE)" "" @@ -79,6 +79,7 @@ init: $(QUIET)$(ECHO) "$@: Done." install: must_be_root + $(QUIET)$(PYTHON) -m pip install --upgrade pip setuptools wheel || true $(QUIET)$(PYTHON) -m pip install "git+https://github.com/reactive-firewall/multicast.git#egg=multicast" $(QUITE)$(WAIT) $(QUIET)$(ECHO) "$@: Done." @@ -99,7 +100,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose -s ./tests -t ./ || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || python -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)$(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); @@ -110,7 +111,7 @@ test-tox: cleanup $(QUIET)$(ECHO) "$@: Done." test-pytest: cleanup test-reports - $(QUIET)$(PYTHON) -m pytest --junitxml=test-reports/junit.xml -v tests || python -m pytest --junitxml=test-reports/junit.xml -v tests + $(QUIET)$(PYTHON) -m pytest --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests $(QUIET)$(ECHO) "$@: Done." test-style: cleanup diff --git a/README.md b/README.md index e9e6eee3..9273788c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Continuous integration testing is handeled by Circle-CI Service. ### master: [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) +[![CI](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml/badge.svg?branch=master)](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml) [![Appveyor](https://ci.appveyor.com/api/projects/status/??????/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) [![Test Coverage](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) [![Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/master/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/master/) diff --git a/setup.cfg b/setup.cfg index 544bf3ad..9cc0f530 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,8 +19,6 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.5 [bdist_rpm] url = https://www.github.com/reactive-firewall/multicast.git @@ -32,8 +30,8 @@ universal=1 packages = multicast [options] -py_modules = piaplib -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +py_modules = multicast +python_requires = >=3.7 packages = find:*.py scripts = multicast/__main__.py diff --git a/setup.py b/setup.py index 7add32d6..db19b9d2 100755 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # .......................................... -# http://www.github.com/reactive-firewall/multicast/LICENSE.md +# http://www.github.com/reactive-firewall/multicast/LICENSE # .......................................... # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/tests/check_codecov b/tests/check_codecov new file mode 100755 index 00000000..9994ffdb --- /dev/null +++ b/tests/check_codecov @@ -0,0 +1,172 @@ +#! /bin/bash +# Disclaimer of Warranties. +# A. YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT, TO THE EXTENT PERMITTED BY +# APPLICABLE LAW, USE OF THIS SHELL SCRIPT AND ANY SERVICES PERFORMED +# BY OR ACCESSED THROUGH THIS SHELL SCRIPT IS AT YOUR SOLE RISK AND +# THAT THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY AND +# EFFORT IS WITH YOU. +# +# B. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SHELL SCRIPT +# AND SERVICES ARE PROVIDED "AS IS" AND “AS AVAILABLE”, WITH ALL FAULTS AND +# WITHOUT WARRANTY OF ANY KIND, AND THE AUTHOR OF THIS SHELL SCRIPT'S LICENSORS +# (COLLECTIVELY REFERRED TO AS "THE AUTHOR" FOR THE PURPOSES OF THIS DISCLAIMER) +# HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH RESPECT TO THIS SHELL SCRIPT +# SOFTWARE AND SERVICES, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +# NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF +# MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, +# ACCURACY, QUIET ENJOYMENT, AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. +# +# C. THE AUTHOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE +# THE AUTHOR's SOFTWARE AND SERVICES, THAT THE FUNCTIONS CONTAINED IN, OR +# SERVICES PERFORMED OR PROVIDED BY, THIS SHELL SCRIPT WILL MEET YOUR +# REQUIREMENTS, THAT THE OPERATION OF THIS SHELL SCRIPT OR SERVICES WILL +# BE UNINTERRUPTED OR ERROR-FREE, THAT ANY SERVICES WILL CONTINUE TO BE MADE +# AVAILABLE, THAT THIS SHELL SCRIPT OR SERVICES WILL BE COMPATIBLE OR +# WORK WITH ANY THIRD PARTY SOFTWARE, APPLICATIONS OR THIRD PARTY SERVICES, +# OR THAT DEFECTS IN THIS SHELL SCRIPT OR SERVICES WILL BE CORRECTED. +# INSTALLATION OF THIS THE AUTHOR SOFTWARE MAY AFFECT THE USABILITY OF THIRD +# PARTY SOFTWARE, APPLICATIONS OR THIRD PARTY SERVICES. +# +# D. YOU FURTHER ACKNOWLEDGE THAT THIS SHELL SCRIPT AND SERVICES ARE NOT +# INTENDED OR SUITABLE FOR USE IN SITUATIONS OR ENVIRONMENTS WHERE THE FAILURE +# OR TIME DELAYS OF, OR ERRORS OR INACCURACIES IN, THE CONTENT, DATA OR +# INFORMATION PROVIDED BY THIS SHELL SCRIPT OR SERVICES COULD LEAD TO +# DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE, +# INCLUDING WITHOUT LIMITATION THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT +# NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, LIFE SUPPORT OR +# WEAPONS SYSTEMS. +# +# E. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY THE AUTHOR +# SHALL CREATE A WARRANTY. SHOULD THIS SHELL SCRIPT OR SERVICES PROVE DEFECTIVE, +# YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +# +# Limitation of Liability. +# F. TO THE EXTENT NOT PROHIBITED BY APPLICABLE LAW, IN NO EVENT SHALL THE AUTHOR +# BE LIABLE FOR PERSONAL INJURY, OR ANY INCIDENTAL, SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES +# FOR LOSS OF PROFITS, CORRUPTION OR LOSS OF DATA, FAILURE TO TRANSMIT OR +# RECEIVE ANY DATA OR INFORMATION, BUSINESS INTERRUPTION OR ANY OTHER +# COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR +# INABILITY TO USE THIS SHELL SCRIPT OR SERVICES OR ANY THIRD PARTY +# SOFTWARE OR APPLICATIONS IN CONJUNCTION WITH THIS SHELL SCRIPT OR +# SERVICES, HOWEVER CAUSED, REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, +# TORT OR OTHERWISE) AND EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION +# OR LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF INCIDENTAL OR +# CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event +# shall THE AUTHOR's total liability to you for all damages (other than as may +# be required by applicable law in cases involving personal injury) exceed +# the amount of five dollars ($5.00). The foregoing limitations will apply +# even if the above stated remedy fails of its essential purpose. +################################################################################ + +ulimit -t 1200 +PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${PATH}" +LC_ALL="${LANG:1:5}.utf-8" +umask 027 + +LOCK_FILE="/tmp/codecov_test_script_lock" +EXIT_CODE=0 + +test -x $(command -v grep) || exit 126 ; +test -x $(command -v curl) || exit 126 ; +test -x $(command -v shasum) || exit 126 ; + +function cleanup() { + rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; + rm -f ./codecov 2>/dev/null || true ; wait ; +} + +if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then + trap 'cleanup ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 + trap 'cleanup ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 + trap 'cleanup ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 + trap 'cleanup ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 + trap 'cleanup ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 + trap 'cleanup ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 + trap 'cleanup ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 +else + echo CodeCov already in progress by `head ${LOCK_FILE}` ; + false ; + exit 126 ; +fi + +# this is how test files are found: + +# THIS IS THE ACTUAL TEST DIR USED (update _TEST_ROOT_DIR as needed) +_TEST_ROOT_DIR="./" ; +if [[ -d ./multicast ]] ; then + _TEST_ROOT_DIR="./multicast" ; + _TEST_ROOT_DIR="./" ; +elif [[ -d ./tests ]] ; then + _TEST_ROOT_DIR="./" ; +else + echo "FAIL: missing valid folder or file" + EXIT_CODE=1 +fi + +# This File MUST BE GIT-IGNORED to be SAFELY USED to store Tokens and env vars (update logic as needed) +if [[ ( -r ./codecov_env ) ]] ; then + source ./codecov_env 2>/dev/null || true ; +fi + +if [[ ( -r ./codecov.yml ) ]] ; then + cat codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 +fi +if [[ ( -r ./.codecov.yml ) ]] ; then + cat ./.codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 +fi + +# sorry no windows support here +if [[ $( \uname -s ) == "Darwin" ]] ; then + CI_OS="macos" +else + CI_OS="linux" +fi + +######################### +# actual Work starts here +######################### +curl -fLso codecov https://uploader.codecov.io/latest/${CI_OS:-linux}/codecov ; +for i in 1 256 512 ; do + curl -fLso codecov.SHA${i}SUM "https://uploader.codecov.io/latest/${CI_OS:-linux}/codecov.SHA${i}SUM" ; wait ; + curl -fLso codecov.SHA${i}SUM.sig "https://uploader.codecov.io/latest/${CI_OS:-linux}/codecov.SHA${i}SUM.sig" ; wait ; + # test sha1/sha512 signatures if found and sha256 even if not found + if [[ ( -r codecov.SHA${i}SUM ) ]] || [[ ( ${i} -eq 256 ) ]] ; then + if [[ ( -r codecov.SHA${i}SUM.sig ) ]] ; then + # configure your CI evironment to trust the key at https://keybase.io/codecovsecurity/pgp_keys.asc + # FP: 2703 4E7F DB85 0E0B BC2C 62FF 806B B28A ED77 9869 + # OR... + # Set CI=true to continue on missing keys + gpgv codecov.SHA${i}SUM.sig codecov.SHA${i}SUM || ${CI} || EXIT_CODE=126 + rm -vf codecov.SHA${i}SUM.sig 2>/dev/null ; + fi + shasum -a $i -c --ignore-missing codecov.SHA${i}SUM || EXIT_CODE=126 + rm -vf codecov.SHA${i}SUM 2>/dev/null ; + fi +done + +if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then + chmod -v 751 ./codecov || EXIT_CODE=126 +fi + +if [[ ( -x $(command -v coverage3) ) ]] ; then + coverage3 combine 2>/dev/null || true + coverage3 xml 2>/dev/null || true +elif [[ ( -x $(command -v coverage) ) ]] ; then + coverage combine 2>/dev/null || true + coverage xml 2>/dev/null || true +fi + +if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then + ./codecov -n "Custom Test Run" -X gcov -F unittests || EXIT_CODE=5 ; +fi + + +unset _TEST_ROOT_DIR 2>/dev/null || true ; + +rm -f ${LOCK_FILE} 2>/dev/null > /dev/null || true ; wait ; +rm -f ./codecov 2>/dev/null > /dev/null || true ; wait ; + +# goodbye +exit ${EXIT_CODE:-255} ; From 622abb3b70539729ca57f434cc3b5f86ec603b2f Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 05:34:02 -0800 Subject: [PATCH 046/135] [STYLE] fix for appvoyer CI badge --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9273788c..b3ed8eb5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Continuous integration testing is handeled by Circle-CI Service. ### master: [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) [![CI](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml/badge.svg?branch=master)](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml) -[![Appveyor](https://ci.appveyor.com/api/projects/status/??????/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) +[![Appveyor](https://ci.appveyor.com/api/projects/status/0h5vuexyty9lbl81/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) [![Test Coverage](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/test_coverage)](https://codeclimate.com/github/reactive-firewall/multicast/test_coverage) [![Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/master/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/master/) [![Code Climate](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/maintainability)](https://codeclimate.com/github/reactive-firewall/multicast) @@ -25,7 +25,7 @@ Continuous integration testing is handeled by Circle-CI Service. ### Stable: [![Stable-CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/stable.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/stable) -[![Atable-Appveyor](https://ci.appveyor.com/api/projects/status/????/branch/stable?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/stable) +[![Atable-Appveyor](https://ci.appveyor.com/api/projects/status/0h5vuexyty9lbl81/branch/stable?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/stable) [![stable-code-coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/) [![Staqble Codebeat Badge](https://codebeat.co/badges/????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-stable) From 50f7c113e47b4bbaee70bf50ec7dece717364dbd Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 20:28:19 -0800 Subject: [PATCH 047/135] [STYLE] Fix for W293 blank line contains whitespace in __main__.py --- multicast/__main__.py | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/multicast/__main__.py b/multicast/__main__.py index 0abbb5e7..20548fb0 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -119,7 +119,7 @@ def NoOp(*args, **kwargs): """The meaning of Nothing. This function should be self-explanitory; it does 'no operation' i.e. nothing. - + Minimal Acceptance Testing: First setup test fixtures by importing multicast. @@ -209,7 +209,39 @@ def parseArgs(arguments=None): def __checkToolArgs(args): - """Handles None case for arguments as a helper function.""" + """Handles None case for arguments as a helper function. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> + + Testcase 0: multicast.__main__ should have a doctests. + + >>> import multicast.__main__ + >>> multicast.__main__.__module__ is not None + True + >>> + + Testcase 1: multicast.__checkToolArgs should return an array. + + >>> import multicast.__main__ + >>> multicast.__main__.__checkToolArgs(None) is not None + True + >>> type(multicast.__main__.__checkToolArgs(None)) is type([None]) + True + >>> + + Testcase 2: multicast.__checkToolArgs should return an array. + + >>> import multicast.__main__ + >>> type(multicast.__main__.__checkToolArgs(["arg1", "arg2"])) is type(["strings"]) + True + >>> + + """ if args is None: args = [None] return args From 3da58c9e13682a68db941c0e7e932eb5353c8693 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 20:42:37 -0800 Subject: [PATCH 048/135] [STYLE] Fix for W293 blank lines contains whitespace in recv.py --- multicast/recv.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index 03ef3e8b..1d37df77 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -152,7 +152,7 @@ def run(groups, port, iface=None, bind_group=None): this module/instance, but it is also possible to bind to group which is added by some other programs (like another python program instance of this) """ - + # assert bind_group in groups + [None], \ # 'bind group not in groups to join' sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) @@ -160,7 +160,8 @@ def run(groups, port, iface=None, bind_group=None): # allow reuse of socket (to allow another instance of python running this # script binding to the same ip/port) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - + + recvBuffer = str("""""") try: sock.bind(('' if bind_group is None else bind_group, port)) for group in groups: @@ -172,7 +173,7 @@ def run(groups, port, iface=None, bind_group=None): sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) while True: - print(sock.recv(1316)) + recvBuffer.join(sock.recv(1316)) # about 969 bytes in base64 encoded as chars except KeyboardInterrupt: print("") @@ -184,6 +185,7 @@ def run(groups, port, iface=None, bind_group=None): except OSError: False sock = None + print(str(recvBuffer)) def main(*argv): @@ -191,7 +193,7 @@ def main(*argv): 1: calls parseArgs() and passes the given arguments, handling any errors if needed. 2: calls run with the parsed args if able and handles any errors regardles - + Regardles of errors the result as an 'exit code' (int) is returned. (Note the __main__ handler just exits with this code as a true return code status.) """ From 54fba63cc4ecf40afcd6b3d0dab6c6e87d09fdd0 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 20:59:01 -0800 Subject: [PATCH 049/135] [STYLE] Fix for F401 'tests.context' imported but unused --- tests/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/__init__.py b/tests/__init__.py index db988670..5e2f0d9b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -105,13 +105,21 @@ exit(0) -from tests import context +try: + if 'tests.context' not in sys.modules: + from tests import context + else: # pragma: no branch + context = sys.modules["""tests.context"""] +except Exception: # pragma: no branch + raise ImportError("[CWE-440] context Failed to import.") + test_cases = ( test_basic.BasicTestSuite, test_usage.MulticastTestSuite, test_usage.BasicIntegrationTestSuite ) + def load_tests(loader, tests, pattern): import doctest finder = doctest.DocTestFinder(verbose=True, recurse=True, exclude_empty=True) From f442a65c0c77fa3a72d06619af9cef929b5bdba5 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 21:26:47 -0800 Subject: [PATCH 050/135] [STYLE] Fix for W293 blank lines contains whitespace in context.py --- tests/context.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/context.py b/tests/context.py index ac1a6382..587c4b85 100644 --- a/tests/context.py +++ b/tests/context.py @@ -23,11 +23,11 @@ __doc__ = """ Context for Testing. - + Meta Tests - Fixtures: - + Test fixtures by importing test context. - + >>> import tests.context as context >>> @@ -116,7 +116,7 @@ def getPythonCommand(): >>> Testcase 1: function should have a output. - + >>> tests.context.getPythonCommand() is not None True >>> @@ -431,7 +431,7 @@ class BasicUsageTestSuite(unittest.TestCase): @classmethod def setUpClass(cls): cls._thepython = getPythonCommand() - + def setUp(self): """ Overides unittest.TestCase.setUp(unittest.TestCase). From eba081abf703b5f8219ec8771326d4b8927180ef Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 21:38:34 -0800 Subject: [PATCH 051/135] [CONFIG] update git atters --- .gitattributes | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitattributes b/.gitattributes index ed62237c..039b93e5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,14 +3,14 @@ *.txt text *.py text working-tree-encoding=UTF-8 diff=python *.sh text -*.bash text +*.bash text diff=shell *.ini text *.md text *.yml text *.jpg -text *.png -text -*.conf text +*.conf text diff=config *.bat text *.rst text -tests/check_* text +tests/check_* text working-tree-encoding=UTF-8 diff=shell Makefile text diff=makefile From 1fe01ab34914a652344ddd68cc086a6686aa62c9 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 22:07:47 -0800 Subject: [PATCH 052/135] [TESTS] Improved the integration test-flow a little for clearity --- multicast/send.py | 11 +++++++++-- tests/test_usage.py | 6 ++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/multicast/send.py b/multicast/send.py index d3c7a3d7..17212460 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -134,8 +134,15 @@ def parseArgs(*arguments): def run(group, port, data): MULTICAST_TTL = 20 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL) - sock.sendto(data.encode('utf8'), (group, port)) + try: + sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL) + sock.sendto(data.encode('utf8'), (group, port)) + finally: + try: + sock.close() + except OSError: + False + sock = None def main(*argv): diff --git a/tests/test_usage.py b/tests/test_usage.py index 328d50b6..a4c4d715 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -143,6 +143,7 @@ def setUp(self): def test_run_lib_command_plain(self): """Test case for multicast.__main__ help.""" theResult = False + fail_fixture = str("""multicast.__main__(--help) == not helpful""") try: if (self._thepython is not None): theOutputtext = context.checkPythonCommand([ @@ -161,6 +162,7 @@ def test_run_lib_command_plain(self): context.debugtestError(err) err = None del err + self.fail(fail_fixture) theResult = False self.assertTrue(theResult, str("""Could Not find usage from multicast --help""")) @@ -224,7 +226,7 @@ def test_version_has_value_case(self): err = None del err theResult = False - assert theResult + self.assertTrue(theResult, str("""Could Not find version from multicast --version""")) def test_profile_template_case(self): """Test case template for profiling""" @@ -276,7 +278,7 @@ def test_fail_message_works_case(self): ) ) ] - theOutputtext = context.timePythonCommand(args, stderr=subprocess.STDOUT) + theOutputtext = context.checkPythonCommand(args, stderr=subprocess.STDOUT) # now test it try: if isinstance(theOutputtext, bytes): From 8ad8fdd05ccc0a06fc4ccc2212af94e86f563afe Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 20 Jan 2022 23:28:00 -0800 Subject: [PATCH 053/135] [TESTS] fixed a logic typo in coverage script --- tests/check_codecov | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check_codecov b/tests/check_codecov index 9994ffdb..c679727d 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -159,7 +159,7 @@ elif [[ ( -x $(command -v coverage) ) ]] ; then fi if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then - ./codecov -n "Custom Test Run" -X gcov -F unittests || EXIT_CODE=5 ; + ./codecov -n "Custom Test Run" -X gcov -F ${CI_OS:-linux} || EXIT_CODE=5 ; fi From a18c11a3f512dc299fa59d8d4f66450c7c350acf Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 00:27:16 -0800 Subject: [PATCH 054/135] [TESTS] Improvement for visibility via CI-testing with pytest doctests --- .appveyor.yml | 12 +++++++++--- .circleci/config.yml | 19 +++++++++++++++---- Makefile | 3 ++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index f5e38c29..d8f2dcc9 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,9 +20,15 @@ init: choco upgrade python --pre || VER>NUL - python3 -m pip install flake8 || VER>NUL + python -m pip install flake8 || VER>NUL - python3 -m pip install coverage || VER>NUL + python -m pip install coverage || VER>NUL + + python -m pip install --upgrade doctest || VER>NUL + + python -m pip install pytest || VER>NUL + + python -m pip install pytest-cov || VER>NUL choco install codecov || VER>NUL @@ -31,7 +37,7 @@ build_script: - cmd: make clean test_script: - cmd: >- - make test || VER>NUL + make test-pytest || VER>NUL dir diff --git a/.circleci/config.yml b/.circleci/config.yml index 77112264..ddf5fbaa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,6 +5,7 @@ jobs: - image: circleci/python:3.7 - image: circleci/python:3.8 - image: circleci/python:3.9 + resource_class: medium environment: CI: cicleci DEBIAN_FRONTEND: noninteractive @@ -28,11 +29,11 @@ jobs: shell: /bin/bash name: "install coverage attempt" command: | - python3 -m pip install --user coverage || true + python3 -m pip install --upgrade --user coverage || true - run: name: "install flake8 attempt" command: | - python3 -m pip install --user flake8 || true + python3 -m pip install --upgrade --user flake8 || true when: on_success - save_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} @@ -45,6 +46,7 @@ jobs: - image: circleci/python:3.8 - image: circleci/python:3.9 parallelism: 2 + resource_class: medium environment: CI: cicleci DEBIAN_FRONTEND: noninteractive @@ -65,7 +67,7 @@ jobs: shell: /bin/bash name: "Installing newer deps" command: | - python3 -m pip install --user coverage3 || true + python3 -m pip install --upgrade --user coverage3 || true when: on_fail - run: shell: /bin/bash @@ -98,6 +100,7 @@ jobs: - image: circleci/python:3.8 - image: circleci/python:3.9 parallelism: 2 + resource_class: medium environment: CI: cicleci DEBIAN_FRONTEND: noninteractive @@ -108,11 +111,17 @@ jobs: steps: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} + - run: + shell: /bin/bash + name: "setup for doctest" + command: | + python3 -m pip install --upgrade --user doctest || true + when: on_success - run: shell: /bin/bash name: "clean up for test" command: | - python3 -m pip install --user coverage || true + python3 -m pip install --upgrade --user coverage || true when: on_success - run: shell: /bin/bash @@ -160,6 +169,7 @@ jobs: lint: docker: - image: circleci/python:3.9 + resource_class: medium environment: CI: cicleci DEBIAN_FRONTEND: noninteractive @@ -204,3 +214,4 @@ workflows: - pytest: requires: - build + - test diff --git a/Makefile b/Makefile index 76a87956..71097c4f 100644 --- a/Makefile +++ b/Makefile @@ -97,6 +97,7 @@ purge: clean uninstall $(QUIET)$(PYTHON) -m pip uninstall multicast && python -m pip uninstall multicast || true $(QUIET)rm -Rfd ./build/ 2>/dev/null || true $(QUIET)rm -Rfd ./.eggs/ 2>/dev/null || true + $(QUIET)rm -Rfd ./test-reports/ 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." test: cleanup @@ -111,7 +112,7 @@ test-tox: cleanup $(QUIET)$(ECHO) "$@: Done." test-pytest: cleanup test-reports - $(QUIET)$(PYTHON) -m pytest --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests + $(QUIET)$(PYTHON) -m pytest --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests || python -m pytest --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests ; wait ; $(QUIET)$(ECHO) "$@: Done." test-style: cleanup From 0b04d78a9e69f5e9470e829412b039068efc573a Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 00:46:14 -0800 Subject: [PATCH 055/135] [STYLE] Fix for codebeat.io badge in README.md --- README.md | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b3ed8eb5..51d98ef3 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,21 @@ -# About +# Multicast Python Repo + +## About + This repo is basically a wrapper for sending and reciveing UDP multicast messages via python. Y.M.M.V. This library is not intended to fully implement the complexeties of multicast traffic, rather to allow a user friendly API for python components to send and recieve accross a multicast transmission. The obvious advantage of this wrapper over unicast solotions is the ability to have multiple nodes comunicate concurently without individual conections for each node pair. -# CI (WIP): +## CI: -Continuous integration testing is handeled by Circle-CI Service. +Continuous integration testing is handeled by github actions and the generous Circle-CI Service. ## Status ### master: + [![CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/master.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/master) [![CI](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml/badge.svg?branch=master)](https://github.com/reactive-firewall/multicast/actions/workflows/Tests.yml) [![Appveyor](https://ci.appveyor.com/api/projects/status/0h5vuexyty9lbl81/branch/master?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/master) @@ -19,17 +23,19 @@ Continuous integration testing is handeled by Circle-CI Service. [![Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/master/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/master/) [![Code Climate](https://api.codeclimate.com/v1/badges/8a9422860b6a5b6477b5/maintainability)](https://codeclimate.com/github/reactive-firewall/multicast) [![CodeFactor](https://www.codefactor.io/repository/github/reactive-firewall/multicast/badge)](https://www.codefactor.io/repository/github/reactive-firewall/multicast) -[![Codebeat badge](https://codebeat.co/badges/?????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-master) +[![codebeat badge](https://codebeat.co/badges/721f752f-289d-457e-af90-487a85f16bf1)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-master) ![Size](https://img.shields.io/github/languages/code-size/reactive-firewall/multicast.svg) ![Commits-since](https://img.shields.io/github/commits-since/reactive-firewall/multicast/stable.svg?maxAge=9000) ### Stable: + [![Stable-CircleCI](https://circleci.com/gh/reactive-firewall/multicast/tree/stable.svg?style=svg)](https://circleci.com/gh/reactive-firewall/multicast/tree/stable) [![Atable-Appveyor](https://ci.appveyor.com/api/projects/status/0h5vuexyty9lbl81/branch/stable?svg=true)](https://ci.appveyor.com/project/reactive-firewall/multicast/branch/stable) [![stable-code-coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/) -[![Staqble Codebeat Badge](https://codebeat.co/badges/????)](https://codebeat.co/projects/github-com-reactive-firewall-multicast-stable) -# How do I get this running? +## FAQ + +### How do I get this running? (assuming python3 is setup and installed) @@ -43,10 +49,11 @@ python3 -m multicast --help ; ``` #### DONE + if all went well multicast is installed and working -# How do I use this to recive UDP Multicast? +### How do I use this to recive UDP Multicast? (assuming project is setup and installed and you want to listen on 0.0.0.0) @@ -55,7 +62,7 @@ if all went well multicast is installed and working python3 -m multicast HEAR --iface='0.0.0.0' --join-mcast-group 224.1.1.2 --bind-group '224.1.1.2' --port 5353 ``` -# How do I use this to send UDP Multicast? +### How do I use this to send UDP Multicast? (assuming project is setup and installed) @@ -64,9 +71,9 @@ python3 -m multicast HEAR --iface='0.0.0.0' --join-mcast-group 224.1.1.2 --bind- python3 -m multicast SAY --mcast-group 224.1.1.2 --port 5353 --message "Hello World!" ``` -# Dev Testing: +## Dev Testing: -In a rush? Then use this: +#### In a debug rush? Then use this to test: ```bash make clean ; # cleans up from any previous tests hopefully @@ -74,7 +81,7 @@ make test ; # runs the tests make clean ; # cleans up for next test ``` -Use PEP8 to check code style? Great! Try this: +#### Use PEP8 to check python code style? Great! Try this: ```bash make clean ; # cleans up from any previous tests hopefully @@ -82,7 +89,7 @@ make test-style ; # runs the tests make clean ; # cleans up for next test ``` -Want more tests? Cool! Try `tox`: +#### Want more tests? Cool! Try `tox`: ```bash make clean ; # cleans up from any previous tests hopefully @@ -90,11 +97,13 @@ make test-tox ; # runs the tox tests make clean ; # cleans up for next test ``` -# Next steps: +## Next steps: +(UNSTABLE) clean up Proof-of-concept code into a recognizable python module project. +(WIP) might expand the documentation to be more user friendly to the non-network guru (WIP) might add tcp multicast ... who knows? - #### Copyright (c) 2021-2022, Mr. Walls + [![License - MIT](https://img.shields.io/github/license/reactive-firewall/multicast.svg?maxAge=3600)](https://github.com/reactive-firewall/multicast/blob/stable/LICENSE.md) From 96038e89fe9588a3666a8cfac16377aefd2172cc Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 02:30:27 -0800 Subject: [PATCH 056/135] [STYLE] fixed some linter barff --- multicast/recv.py | 2 +- tests/__init__.py | 10 ++++----- tests/context.py | 52 ++++++++++++++++++++++++++++++++++++--------- tests/test_usage.py | 2 -- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index 1d37df77..6a730dc7 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -153,7 +153,7 @@ def run(groups, port, iface=None, bind_group=None): is added by some other programs (like another python program instance of this) """ - # assert bind_group in groups + [None], \ + # assert bind_group in groups + [None], \ # 'bind group not in groups to join' sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) diff --git a/tests/__init__.py b/tests/__init__.py index 5e2f0d9b..ab6af0ea 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -106,12 +106,12 @@ try: - if 'tests.context' not in sys.modules: - from tests import context - else: # pragma: no branch - context = sys.modules["""tests.context"""] + if 'tests.context' not in sys.modules: + from tests import context + else: # pragma: no branch + context = sys.modules["""tests.context"""] except Exception: # pragma: no branch - raise ImportError("[CWE-440] context Failed to import.") + raise ImportError("[CWE-440] context Failed to import.") test_cases = ( diff --git a/tests/context.py b/tests/context.py index b8a2acd0..24a2bb9c 100644 --- a/tests/context.py +++ b/tests/context.py @@ -101,9 +101,9 @@ raise ImportError("[CWE-440] profiling Failed to import.") -def getPythonCommand(): +def getCoverageCommand(): """ - Function for backend python command. + Function for backend coverage command. Rather than just return the sys.executable which will usually be a python implementation, this function will search for a coverage tool to allow coverage testing to continue beyond the process fork of typical cli testing. @@ -117,6 +117,41 @@ def getPythonCommand(): Testcase 1: function should have a output. + >>> tests.context.getCoverageCommand() is not None + True + >>> + + + """ + thecov = "exit 1 ; #" + try: + thecov = checkPythonCommand(["command", "-v", "coverage"]) + if (str("/coverage") in str(thecov)): + thecov = str("coverage") + elif str("/coverage3") in str(checkPythonCommand(["command", "-v", "coverage3"])): + thecov = str("coverage3") + else: + thecov = "exit 1 ; #" + except Exception: + thecov = "exit 1 ; #" + return str(thecov) + + +def getPythonCommand(): + """ + Function for backend python command. + Rather than just return the sys.executable which will usually be a python implementation, + this function will search for a coverage tool with getCoverageCommand() first. + + Meta Testing: + + First setup test fixtures by importing test context. + + >>> import tests.context + >>> + + Testcase 1: function should have a output. + >>> tests.context.getPythonCommand() is not None True >>> @@ -124,21 +159,18 @@ def getPythonCommand(): """ thepython = "exit 1 ; #" try: - thepython = checkPythonCommand(["command", "-v", "coverage"]) + thepython = getCoverageCommand() if (sys.version_info >= (3, 3)): - if (str("/coverage") in str(thepython)) and (sys.version_info >= (3, 3)): - thepython = str("coverage run -p") - elif str("/coverage3") in str(checkPythonCommand(["command", "-v", "coverage3"])): - thepython = str("coverage3 run -p") + if (str("coverage") in str(thepython)) and (sys.version_info >= (3, 3)): + thepython += str(" run -p") else: thepython = str(sys.executable) - elif (str("/coverage") in str(thepython)) and (sys.version_info <= (3, 2)): + elif (str("coverage") in str(thepython)) and (sys.version_info <= (3, 2)): + thepython = str(sys.executable) try: import coverage if coverage.__name__ is not None: thepython = str("{} -m coverage run -p").format(str(sys.executable)) - else: - thepython = str(sys.executable) except Exception: thepython = str(sys.executable) else: diff --git a/tests/test_usage.py b/tests/test_usage.py index a4c4d715..221ab39d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -37,9 +37,7 @@ else: from context import multicast from context import unittest as unittest - from context import os as os from context import subprocess as subprocess - from context import profiling as profiling except Exception: raise ImportError("[CWE-758] Failed to import test context") From 8ba92c36455f04c87d06f7825b63af2c98ffa286 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 02:53:28 -0800 Subject: [PATCH 057/135] [STYLE] reduced some complexity in test utilities --- tests/context.py | 84 +++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/tests/context.py b/tests/context.py index 24a2bb9c..019eecbb 100644 --- a/tests/context.py +++ b/tests/context.py @@ -137,6 +137,25 @@ def getCoverageCommand(): return str(thecov) +def __check_cov_before_py(): + """ + Utility Function to check for coverage before just python. + """ + thepython = str(sys.executable) + thecov = getCoverageCommand() + if (sys.version_info >= (3, 3)): + if (str("coverage") in str(thecov)) and (sys.version_info >= (3, 3)): + thepython += str(" run -p") + elif (str("coverage") in str(thecov)) and (sys.version_info <= (3, 2)): + try: + import coverage + if coverage.__name__ is not None: + thepython = str("{} -m coverage run -p").format(str(sys.executable)) + except Exception: + thepython = str(sys.executable) + return thepython + + def getPythonCommand(): """ Function for backend python command. @@ -159,22 +178,7 @@ def getPythonCommand(): """ thepython = "exit 1 ; #" try: - thepython = getCoverageCommand() - if (sys.version_info >= (3, 3)): - if (str("coverage") in str(thepython)) and (sys.version_info >= (3, 3)): - thepython += str(" run -p") - else: - thepython = str(sys.executable) - elif (str("coverage") in str(thepython)) and (sys.version_info <= (3, 2)): - thepython = str(sys.executable) - try: - import coverage - if coverage.__name__ is not None: - thepython = str("{} -m coverage run -p").format(str(sys.executable)) - except Exception: - thepython = str(sys.executable) - else: - thepython = str(sys.executable) + thepython = __check_cov_before_py() except Exception: thepython = "exit 1 ; #" try: @@ -184,6 +188,32 @@ def getPythonCommand(): return str(thepython) +def checkCovCommand(*args): + """Utility Function.""" + if sys.__name__ is None: + raise ImportError("[CWE-758] Failed to import system. WTF?!!") + if str("{} -m coverage ").format(str(sys.executable)) in str(args[0]): + args[0] = str(sys.executable) + args.insert(1, str("-m")) + args.insert(2, str("coverage")) + args.insert(3, str("run")) + args.insert(4, str("-p")) + args.insert(5, str("--source=multicast")) + elif str("{} -m coverage3 ").format(str(sys.executable)) in str(args[0]): + args[0] = str(sys.executable) + args.insert(1, str("-m")) + args.insert(2, str("coverage3")) + args.insert(3, str("run")) + args.insert(4, str("-p")) + args.insert(5, str("--source=multicast")) + else: + args[0] = str("coverage") + args.insert(1, str("run")) + args.insert(2, str("-p")) + args.insert(3, str("--source=multicast")) + args.insert(3, str("--source=multicast")) + return args + def checkPythonCommand(args=[None], stderr=None): """function for backend subprocess check_output command""" theOutput = None @@ -192,27 +222,7 @@ def checkPythonCommand(args=[None], stderr=None): theOutput = subprocess.check_output(["exit 1 ; #"]) else: if str("coverage ") in args[0]: - if sys.__name__ is None: - raise ImportError("[CWE-758] Failed to import system. WTF?!!") - if str("{} -m coverage ").format(str(sys.executable)) in str(args[0]): - args[0] = str(sys.executable) - args.insert(1, str("-m")) - args.insert(2, str("coverage")) - args.insert(3, str("run")) - args.insert(4, str("-p")) - args.insert(5, str("--source=multicast")) - elif str("{} -m coverage3 ").format(str(sys.executable)) in str(args[0]): - args[0] = str(sys.executable) - args.insert(1, str("-m")) - args.insert(2, str("coverage3")) - args.insert(3, str("run")) - args.insert(4, str("-p")) - args.insert(5, str("--source=multicast")) - else: - args[0] = str("coverage") - args.insert(1, str("run")) - args.insert(2, str("-p")) - args.insert(3, str("--source=multicast")) + args = checkCovCommand(args) theOutput = subprocess.check_output(args, stderr=stderr) except Exception as err: theOutput = None From 7d03fef0b45504ed6c59dffc7555035a2b927437 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 03:08:21 -0800 Subject: [PATCH 058/135] [STYLE] reduced some complexity in test utilities --- tests/context.py | 7 +++---- tests/test_usage.py | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/context.py b/tests/context.py index 019eecbb..5b7ead64 100644 --- a/tests/context.py +++ b/tests/context.py @@ -145,7 +145,7 @@ def __check_cov_before_py(): thecov = getCoverageCommand() if (sys.version_info >= (3, 3)): if (str("coverage") in str(thecov)) and (sys.version_info >= (3, 3)): - thepython += str(" run -p") + thecov += str(" run -p") elif (str("coverage") in str(thecov)) and (sys.version_info <= (3, 2)): try: import coverage @@ -188,7 +188,7 @@ def getPythonCommand(): return str(thepython) -def checkCovCommand(*args): +def checkCovCommand(args=[None]): """Utility Function.""" if sys.__name__ is None: raise ImportError("[CWE-758] Failed to import system. WTF?!!") @@ -211,7 +211,6 @@ def checkCovCommand(*args): args.insert(1, str("run")) args.insert(2, str("-p")) args.insert(3, str("--source=multicast")) - args.insert(3, str("--source=multicast")) return args def checkPythonCommand(args=[None], stderr=None): @@ -221,7 +220,7 @@ def checkPythonCommand(args=[None], stderr=None): if args is None or args is [None]: theOutput = subprocess.check_output(["exit 1 ; #"]) else: - if str("coverage ") in args[0]: + if str("coverage") in args[0]: args = checkCovCommand(args) theOutput = subprocess.check_output(args, stderr=stderr) except Exception as err: diff --git a/tests/test_usage.py b/tests/test_usage.py index 221ab39d..2853895d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -36,8 +36,10 @@ raise ImportError("[CWE-758] Failed to import context") else: from context import multicast + from context import os as os from context import unittest as unittest from context import subprocess as subprocess + from context import profiling as profiling except Exception: raise ImportError("[CWE-758] Failed to import test context") From b49aee55296519b3e8c42d92832bee196a13776d Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 03:17:58 -0800 Subject: [PATCH 059/135] [STYLE] reduced some more complexity in test utilities --- tests/context.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/context.py b/tests/context.py index 5b7ead64..812cf936 100644 --- a/tests/context.py +++ b/tests/context.py @@ -213,6 +213,18 @@ def checkCovCommand(args=[None]): args.insert(3, str("--source=multicast")) return args + +def checkStrOrByte(theInput): + theOutput = None + try: + theOutput = theInput + if isinstance(theInput, bytes): + theOutput = theInput.decode("""utf_8""") + except UnicodeDecodeError: + theOutput = bytes(theInput) + return theOutput + + def checkPythonCommand(args=[None], stderr=None): """function for backend subprocess check_output command""" theOutput = None @@ -228,15 +240,9 @@ def checkPythonCommand(args=[None], stderr=None): try: if err.output is not None: theOutput = err.output - except Exception as cascadeErr: + except Exception: theOutput = None - cascadeErr = None - del cascadeErr - try: - if isinstance(theOutput, bytes): - theOutput = theOutput.decode("""utf_8""") - except UnicodeDecodeError: - theOutput = bytes(theOutput) + theOutput = checkStrOrByte(theOutput) return theOutput From 506ce40d06fc63c383a3d243bad41d0bdf4d8fd9 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 03:35:37 -0800 Subject: [PATCH 060/135] [STYLE] removed some linter snags --- tests/test_usage.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_usage.py b/tests/test_usage.py index 2853895d..221ab39d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -36,10 +36,8 @@ raise ImportError("[CWE-758] Failed to import context") else: from context import multicast - from context import os as os from context import unittest as unittest from context import subprocess as subprocess - from context import profiling as profiling except Exception: raise ImportError("[CWE-758] Failed to import test context") From 60dfe045648a1698de47482caaf81f18a6bce1fc Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 04:51:45 -0800 Subject: [PATCH 061/135] [TESTS] Slight increase in testing code coverage --- Makefile | 8 ++++---- tests/test_usage.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 71097c4f..3633b675 100644 --- a/Makefile +++ b/Makefile @@ -30,15 +30,15 @@ ifeq "$(MAKE)" "" endif ifeq "$(PYTHON)" "" - PYTHON=export LC_CTYPE="en_US.utf-8" ; python3 -B + PYTHON=export LC_CTYPE="en_US.utf-8" ; `command -v python3` -B endif ifeq "$(COVERAGE)" "" ifeq "$(COVERAGE)" "" - COVERAGE=$(command -v coverage) + COVERAGE=`command -v coverage` endif ifeq "$(COVERAGE)" "" - COVERAGE=$(command -v coverage3) + COVERAGE=`command -v coverage3` endif endif @@ -101,7 +101,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)$(COVERAGE) run -p --include=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); diff --git a/tests/test_usage.py b/tests/test_usage.py index 221ab39d..a3c57396 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -75,6 +75,21 @@ def test_multicast_message_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) + def test_multicast_hear_invalid_arg_main(self): + """Tests the message argument for failure given future tools""" + theResult = False + fail_fixture = str("""multicast.__main__.useTool(HEAR, junk) != 2""") + try: + self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--port", "test"])) + self.assertAlmostEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 2) + theResult = True + except Exception as err: + context.debugtestError(err) + self.fail(fail_fixture) + theResult = False + self.assertTrue(theResult, fail_fixture) + + @unittest.expectedFailure def test_multicast_hexdump_arg_main(self): """Tests the hexdump argument for failure given future tools""" From 04abb669c966d7af466d6cc384d1bea08ce9a2a4 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 04:56:38 -0800 Subject: [PATCH 062/135] [REGRESSION] fix for older python --- tests/test_usage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_usage.py b/tests/test_usage.py index a3c57396..88da6c00 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -81,7 +81,8 @@ def test_multicast_hear_invalid_arg_main(self): fail_fixture = str("""multicast.__main__.useTool(HEAR, junk) != 2""") try: self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--port", "test"])) - self.assertAlmostEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 2) + self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 0) + self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 1) theResult = True except Exception as err: context.debugtestError(err) @@ -89,7 +90,6 @@ def test_multicast_hear_invalid_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - @unittest.expectedFailure def test_multicast_hexdump_arg_main(self): """Tests the hexdump argument for failure given future tools""" From 3a04ee78f26920c98293519c805ed8ef7f76cc04 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 21 Jan 2022 21:09:29 -0800 Subject: [PATCH 063/135] [REGRESSION] fix for logic regression bug --- multicast/recv.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index 6a730dc7..9314bebc 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -161,7 +161,6 @@ def run(groups, port, iface=None, bind_group=None): # script binding to the same ip/port) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - recvBuffer = str("""""") try: sock.bind(('' if bind_group is None else bind_group, port)) for group in groups: @@ -173,7 +172,7 @@ def run(groups, port, iface=None, bind_group=None): sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) while True: - recvBuffer.join(sock.recv(1316)) + print(sock.recv(1316)) # about 969 bytes in base64 encoded as chars except KeyboardInterrupt: print("") @@ -185,7 +184,6 @@ def run(groups, port, iface=None, bind_group=None): except OSError: False sock = None - print(str(recvBuffer)) def main(*argv): From 0ba7e4c95c91fe4624ebfef2cf4cac3d7d3d171f Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 02:58:34 -0800 Subject: [PATCH 064/135] [TESTS] added more coverage tools --- .github/workflows/Tests.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index c4ab48c0..ff989690 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -64,6 +64,8 @@ jobs: OS: ${{ matrix.os }} PYTHON_VERSION: ${{ matrix.python-version }} LANG: "en_US.UTF-8" + CODECLIMATE_REPO_TOKEN: ${{ secrets.CODECLIMATE_TOKEN }} + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} steps: - uses: actions/checkout@master - name: Setup Python ${{ matrix.python-version }} @@ -78,6 +80,14 @@ jobs: pip install pytest ; pip install pytest-cov pip install coverage ; + - name: Install code-climate tools for ${{ matrix.python-version }} + run: | + curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true + chmod +x ./cc-test-reporter 2>/dev/null || truee + ./cc-test-reporter before-build || true + - name: Install deepsource tools for ${{ matrix.python-version }} + run: | + if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else (curl https://deepsource.io/cli | sh) || true ; fi ; - name: Pre-Clean id: clean run: make -j1 -f Makefile clean || true ; @@ -89,10 +99,14 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml directory: . - flags: unittests,${{ matrix.os }},${{ matrix.python-version }} + flags: ${{ matrix.os }},${{ matrix.python-version }} name: multicast-github-${{ matrix.os }}-${{ matrix.python-version }} verbose: true fail_ci_if_error: true + - name: code-climate for ${{ matrix.python-version }} + run: if [ $OS == macos-latest ] ; then echo "SKIP code climate" ; else ./cc-test-reporter after-build --exit-code 0 || true ; fi ; + - name: deepsource for ${{ matrix.python-version }} + run: if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; From 1cc829e8d37a597955c55e70d8fc3dff4db45b84 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 03:04:45 -0800 Subject: [PATCH 065/135] [REGRESSION] fix for syntax regression bug --- .github/workflows/Tests.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index ff989690..7c1a073a 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -83,7 +83,7 @@ jobs: - name: Install code-climate tools for ${{ matrix.python-version }} run: | curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true - chmod +x ./cc-test-reporter 2>/dev/null || truee + chmod +x ./cc-test-reporter 2>/dev/null || true ./cc-test-reporter before-build || true - name: Install deepsource tools for ${{ matrix.python-version }} run: | @@ -104,9 +104,11 @@ jobs: verbose: true fail_ci_if_error: true - name: code-climate for ${{ matrix.python-version }} - run: if [ $OS == macos-latest ] ; then echo "SKIP code climate" ; else ./cc-test-reporter after-build --exit-code 0 || true ; fi ; + run: | + if [ $OS == macos-latest ] ; then echo "SKIP code climate" ; else ./cc-test-reporter after-build --exit-code 0 || true ; fi ; - name: deepsource for ${{ matrix.python-version }} - run: if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; + run: | + if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; From 719105c2b0428da6ef3eeeaf0fe52031febd5248 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 03:26:31 -0800 Subject: [PATCH 066/135] [REGRESSION] fix for syntax regression bug --- .github/workflows/Tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 7c1a073a..b59986bb 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -104,11 +104,11 @@ jobs: verbose: true fail_ci_if_error: true - name: code-climate for ${{ matrix.python-version }} - run: | - if [ $OS == macos-latest ] ; then echo "SKIP code climate" ; else ./cc-test-reporter after-build --exit-code 0 || true ; fi ; + run: ./cc-test-reporter after-build --exit-code 0 + if: ${{ matrix.os }} == "ubuntu-latest" - name: deepsource for ${{ matrix.python-version }} - run: | - if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; + run: | + if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; From d070a0f17c45e96dd14adb8a8f5f10f5d933cad3 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 04:40:32 -0800 Subject: [PATCH 067/135] [REGRESSION] fix for syntax regression bug --- .github/workflows/Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index b59986bb..431ed818 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -104,8 +104,8 @@ jobs: verbose: true fail_ci_if_error: true - name: code-climate for ${{ matrix.python-version }} + if: ${{ runner.os == "Linux" }} run: ./cc-test-reporter after-build --exit-code 0 - if: ${{ matrix.os }} == "ubuntu-latest" - name: deepsource for ${{ matrix.python-version }} run: | if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; From 1f64b55c5eebcac9e0b31de97eddadec27a4ae54 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 04:42:56 -0800 Subject: [PATCH 068/135] [REGRESSION] fix for syntax regression bug --- .github/workflows/Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 431ed818..02831aa3 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -104,7 +104,7 @@ jobs: verbose: true fail_ci_if_error: true - name: code-climate for ${{ matrix.python-version }} - if: ${{ runner.os == "Linux" }} + if: ${{ runner.os }} == "Linux" run: ./cc-test-reporter after-build --exit-code 0 - name: deepsource for ${{ matrix.python-version }} run: | From aeb2b2d68f0c3174965504a4dab1b5dbe79e2eb1 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 04:54:32 -0800 Subject: [PATCH 069/135] [REGRESSION] bypass for syntax regression --- .github/workflows/Tests.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 02831aa3..f8321994 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -81,13 +81,14 @@ jobs: pip install pytest-cov pip install coverage ; - name: Install code-climate tools for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" run: | curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true chmod +x ./cc-test-reporter 2>/dev/null || true ./cc-test-reporter before-build || true - name: Install deepsource tools for ${{ matrix.python-version }} run: | - if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else (curl https://deepsource.io/cli | sh) || true ; fi ; + if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; - name: Pre-Clean id: clean run: make -j1 -f Makefile clean || true ; @@ -105,10 +106,11 @@ jobs: fail_ci_if_error: true - name: code-climate for ${{ matrix.python-version }} if: ${{ runner.os }} == "Linux" - run: ./cc-test-reporter after-build --exit-code 0 + run: | + if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter after-build --exit-code 0 || true ; else echo "SKIP code climate" ; fi ; - name: deepsource for ${{ matrix.python-version }} run: | - if [ $OS == macos-latest ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; + if [ $OS == ubuntu-latest ] ; then ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; else echo "SKIP deepsource" ; fi ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; From ac60548583c5ad4e07bedddb68d18fe09192344d Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 05:05:17 -0800 Subject: [PATCH 070/135] [REGRESSION] fix for windows testing regression bug --- .github/workflows/Tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index f8321994..2ba0d877 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -83,9 +83,9 @@ jobs: - name: Install code-climate tools for ${{ matrix.python-version }} if: ${{ runner.os }} == "Linux" run: | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true - chmod +x ./cc-test-reporter 2>/dev/null || true - ./cc-test-reporter before-build || true + if [ $OS == ubuntu-latest ] ; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true ; fi ; + if [ $OS == ubuntu-latest ] ; then chmod +x ./cc-test-reporter 2>/dev/null || true ; fi + if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter before-build || true ; fi - name: Install deepsource tools for ${{ matrix.python-version }} run: | if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; From 1afdfb08faa3f02507bc60b2b8492a342184f810 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 05:21:05 -0800 Subject: [PATCH 071/135] [REGRESSION] fix for windows regression bug --- .github/workflows/Tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 2ba0d877..7c0290d7 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -82,11 +82,13 @@ jobs: pip install coverage ; - name: Install code-climate tools for ${{ matrix.python-version }} if: ${{ runner.os }} == "Linux" + shell: bash run: | if [ $OS == ubuntu-latest ] ; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true ; fi ; if [ $OS == ubuntu-latest ] ; then chmod +x ./cc-test-reporter 2>/dev/null || true ; fi if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter before-build || true ; fi - name: Install deepsource tools for ${{ matrix.python-version }} + shell: bash run: | if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; - name: Pre-Clean @@ -106,6 +108,7 @@ jobs: fail_ci_if_error: true - name: code-climate for ${{ matrix.python-version }} if: ${{ runner.os }} == "Linux" + shell: bash run: | if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter after-build --exit-code 0 || true ; else echo "SKIP code climate" ; fi ; - name: deepsource for ${{ matrix.python-version }} From d776996dcf177ba98a49c3144d6b82cfa0e6d804 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 22 Jan 2022 05:31:55 -0800 Subject: [PATCH 072/135] [REGRESSION] another workaround for windows --- .github/workflows/Tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 7c0290d7..1dfee097 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -88,6 +88,7 @@ jobs: if [ $OS == ubuntu-latest ] ; then chmod +x ./cc-test-reporter 2>/dev/null || true ; fi if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter before-build || true ; fi - name: Install deepsource tools for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" shell: bash run: | if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; @@ -112,6 +113,8 @@ jobs: run: | if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter after-build --exit-code 0 || true ; else echo "SKIP code climate" ; fi ; - name: deepsource for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" + shell: bash run: | if [ $OS == ubuntu-latest ] ; then ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; else echo "SKIP deepsource" ; fi ; - name: Post-Clean From 0e448eaf83e6cafc17db62e25bb2fe7c2b5da235 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 25 Jan 2022 01:02:21 -0800 Subject: [PATCH 073/135] [TESTS] unstable testing update --- tests/test_usage.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/test_usage.py b/tests/test_usage.py index 88da6c00..46d7e5ec 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -62,11 +62,12 @@ def test_multicast_insane_none(self): self.assertTrue(theResult, fail_fixture) def test_multicast_message_arg_main(self): - """Tests the message argument for failure given future tools""" + """Tests the message argument for expected syntax given simple args""" theResult = False fail_fixture = str("""multicast.__main__.useTool(SAY, message) == error""") try: - self.assertIsNotNone(multicast.__main__.useTool("SAY", ["--message"])) + with self.assertRaises(SystemExit): + self.assertIsNotNone(multicast.__main__.useTool("SAY", ["--message"])) self.assertIsNotNone(multicast.__main__.useTool("SAY", ["--message", "test"])) theResult = True except Exception as err: @@ -76,13 +77,14 @@ def test_multicast_message_arg_main(self): self.assertTrue(theResult, fail_fixture) def test_multicast_hear_invalid_arg_main(self): - """Tests the message argument for failure given future tools""" + """Tests the message argument for failure given invalid input""" theResult = False fail_fixture = str("""multicast.__main__.useTool(HEAR, junk) != 2""") try: - self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--port", "test"])) - self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 0) - self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 1) + with self.assertRaises(SystemExit): + self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--port", "test"])) + self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 0) + self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 1) theResult = True except Exception as err: context.debugtestError(err) @@ -96,7 +98,7 @@ def test_multicast_hexdump_arg_main(self): theResult = False fail_fixture = str("""multicast.__main__.useTool(HEAR, hex) == error""") try: - with self.assertRaises(NotImplementedError, fail_fixture): + with self.assertRaises(NotImplementedError): self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--hex"])) theResult = True except Exception as err: From ed05374cd32c2628dbece4e51d18e8e9ae6d3e32 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 25 Jan 2022 01:04:10 -0800 Subject: [PATCH 074/135] [FIX] improved code coverage a bit --- multicast/__init__.py | 71 ++++++----- multicast/__main__.py | 45 +++---- multicast/recv.py | 287 ++++++++++++++++++++++++++++++++---------- multicast/send.py | 46 +++++-- setup.cfg | 19 +-- setup.py | 25 +++- 6 files changed, 334 insertions(+), 159 deletions(-) diff --git a/multicast/__init__.py b/multicast/__init__.py index b7e73fec..c08e9655 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -33,37 +33,8 @@ global __version__ """The version of this program.""" -__version__ = """1.2.0""" - -global __MCAST_DEFAULT_PORT -""" - Arbitrary port to use by default, though any dynamic and free port would work - - Testing: - - First setup test fixtures by importing multicast. - - >>> import multicast - >>> - - >>> multicast.recv is not None - True - >>> - - Testcase 0: Multicast should have a default port. - A: Test that the __MCAST_DEFAULT_PORT attribute is initialized. - B: Test that the __MCAST_DEFAULT_PORT attribute is an int. - - >>> multicast.__MCAST_DEFAULT_PORT is not None - True - >>> type(multicast.__MCAST_DEFAULT_PORT) is type(1) - True - >>> - -""" - -__MCAST_DEFAULT_PORT = 19991 +__version__ = """1.3.0""" __prolog__ = str("""Python Multicast library version {version}.""").format(version=__version__) @@ -86,7 +57,7 @@ True >>> - Testcase 0: multicast.recv should have a doctests. + Testcase 0: multicast.recv should have a doctests. >>> import multicast.recv >>> @@ -98,6 +69,32 @@ """ +global __MCAST_DEFAULT_PORT +""" + Arbitrary port to use by default, though any dynamic and free port would work. + + Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> + + Testcase 0: Multicast should have a default port. + A: Test that the __MCAST_DEFAULT_PORT attribute is initialized. + B: Test that the __MCAST_DEFAULT_PORT attribute is an int. + + >>> multicast.__MCAST_DEFAULT_PORT is not None + True + >>> type(multicast.__MCAST_DEFAULT_PORT) is type(1) + True + >>> + +""" + +__MCAST_DEFAULT_PORT = 19991 + + try: import sys if sys.__name__ is None: @@ -114,6 +111,14 @@ raise ImportError(err) +try: + import unicodedata + if unicodedata.__name__ is None: + raise ImportError("FAIL: we could not import unicodedata. ABORT.") +except Exception as err: + raise ImportError(err) + + try: import socket if socket.__name__ is None: @@ -147,7 +152,7 @@ send = sys.modules["""multicast.send"""] except Exception as importErr: del importErr - import multicast.recv as send + import multicast.send as send if __name__ in '__main__': @@ -158,8 +163,6 @@ __main__ = sys.modules["""multicast.__main__"""] except Exception: from . import __main__ as __main__ - -if __name__ in '__main__': __EXIT_CODE = 2 if __main__.__name__ is None: raise ImportError(str("Failed to open multicast")) diff --git a/multicast/__main__.py b/multicast/__main__.py index 20548fb0..3d8f1b36 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -17,32 +17,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -__package__ = """multicast""" - +__all__ = ["""__module__""", """__prog__""", """__prolog__""", """__epilog__""", """__doc__""", "NoOp", """SendMCast""", """joinMCast""", """dumpUsage""", """TASK_OPTIONS""", """__checkToolArgs""", """buildArgs""", """main""", """parseArgs""", """useTool"""] -__module__ = """multicast""" +__package__ = """multicast""" +__module__ = """multicast.__main__""" __file__ = """multicast/__main__.py""" +__prog__ = """multicast""" -__prog__ = str("""multicast""") -"""The name of this program is Python Multicast""" - - -__description__ = str( - """Add a Description Here""" -) -"""Contains the description of the program.""" - - -__epilog__ = str( - """Add an epilog here.""" -) -"""Contains the short epilog of the program CLI help text.""" +__prolog__ = """The Main Entrypoint""" +__epilog__ = """Add an epilog here.""" -__doc__ = __description__ + """ +__doc__ = __prolog__ + """ Minimal Acceptance Testing: @@ -59,7 +48,7 @@ True >>> - Testcase 0: multicast.__main__ should have a doctests. + Testcase 0: multicast.__main__ should have a doctests. >>> import multicast.__main__ >>> @@ -127,14 +116,14 @@ def NoOp(*args, **kwargs): >>> import multicast >>> - Testcase 0: multicast.__main__ should have a doctests. + Testcase 0: multicast.__main__ should have a doctests. >>> import multicast.__main__ >>> multicast.__main__.__module__ is not None True >>> - Testcase 1: multicast.NoOp should return None. + Testcase 1: multicast.NoOp should return None. >>> import multicast.__main__ >>> multicast.__main__.NoOp() is None @@ -180,7 +169,7 @@ def buildArgs(): """ parser = argparse.ArgumentParser( prog=__prog__, - description=__description__, + description=__prolog__, epilog=__epilog__, add_help=False ) @@ -218,14 +207,14 @@ def __checkToolArgs(args): >>> import multicast >>> - Testcase 0: multicast.__main__ should have a doctests. + Testcase 0: multicast.__main__ should have a doctests. >>> import multicast.__main__ >>> multicast.__main__.__module__ is not None True >>> - Testcase 1: multicast.__checkToolArgs should return an array. + Testcase 1: multicast.__checkToolArgs should return an array. >>> import multicast.__main__ >>> multicast.__main__.__checkToolArgs(None) is not None @@ -234,7 +223,7 @@ def __checkToolArgs(args): True >>> - Testcase 2: multicast.__checkToolArgs should return an array. + Testcase 2: multicast.__checkToolArgs should return an array. >>> import multicast.__main__ >>> type(multicast.__main__.__checkToolArgs(["arg1", "arg2"])) is type(["strings"]) @@ -284,8 +273,10 @@ def main(*argv): return __EXIT_CODE -if __name__ in '__main__': +if __name__ in u'__main__': __EXIT_CODE = 2 - if (sys.argv is not None) and (len(sys.argv) >= 1): + if (sys.argv is not None) and (len(sys.argv) > 1): __EXIT_CODE = main(sys.argv[1:]) + else: + __EXIT_CODE = main(argv=["""--help"""]) exit(__EXIT_CODE) diff --git a/multicast/recv.py b/multicast/recv.py index 9314bebc..58f23480 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -30,7 +30,7 @@ # .......................................... # NO ASSOCIATION -__all__ = ["""main""", """run""", """parseArgs""", """__module__""", """__name__""", """__doc__"""] +__all__ = ["""genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", """__module__""", """__name__""", """__proc__""", """__prolog__""", """__epilog__""", """__doc__"""] __package__ = """multicast""" @@ -48,44 +48,23 @@ __proc__ = """multicast HEAR""" -__doc__ = """Python Multicast Reciver. - - Minimal Acceptance Testing: - - First setup test fixtures by importing multicast. - - Testcase 0: Multicast should be importable. - - >>> import multicast - >>> - - >>> multicast.__doc__ is not None - True - >>> - - Testcase 1: Recv should be automaticly imported. - A: Test that the multicast component is initialized. - B: Test that the recv component is initialized. - - >>> import multicast - >>> +__epilog__ = """Generally speaking you want to bind to one of the groups you joined in + this module/instance, but it is also possible to bind to group which + is added by some other programs (like another python program instance of this) +""" - >>> multicast is not None - True - >>> multicast.recv is not None - True - >>> +__prolog__ = """Python Multicast Receiver. Spawns a listener for multicast based on arguments.""" -""" try: import sys + import unicodedata import socket import struct import argparse depends = [ - socket, struct, argparse + unicodedata, socket, struct, argparse ] for unit in depends: try: @@ -109,29 +88,151 @@ import multicast.__MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT +def genSocket(): + """Generates an unbound socket.socket object ready to receive network traffic. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.__doc__ is not None + True + >>> + + Testcase 0: Recv should be automaticly imported. + A: Test that the multicast component is initialized. + B: Test that the recv component is initialized. + + >>> multicast is not None + True + >>> multicast.recv is not None + True + >>> + + Testcase 1: Recv should have genSocket() function that returns a socket.socket object. + A: Test that the recv component has the function 'genSocket' + B: Test that the 'genSocket' function returns a socket + + >>> multicast.recv.genSocket is not None + True + >>> multicast.recv.genSocket #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + >>> type(multicast.recv.genSocket) + + >>> type(multicast.recv.genSocket()) + + >>> + + + """ + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + # allow reuse of socket (to allow another instance of python running this + # script binding to the same ip/port) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.settimeout(20) + return sock + + +def endSocket(sock=None): + """Generates an unbound socket.socket object ready to receive network traffic. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.__doc__ is not None + True + >>> + + Testcase 0: Recv should be automaticly imported. + A: Test that the multicast component is initialized. + B: Test that the recv component is initialized. + + >>> multicast is not None + True + >>> multicast.recv is not None + True + >>> + + Testcase 1: Recv should have endSocket() function that takes a socket.socket object and closes it. + A: Test that the recv component has the function 'genSocket' + B: Test that the recv component has the function 'endSocket' + C: Test that the 'endSocket' function returns None when given the genSocket + + >>> multicast.recv.genSocket is not None + True + >>> multicast.recv.endSocket is not None + True + >>> multicast.recv.endSocket #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + >>> type(multicast.recv.endSocket) + + >>> temp_fxtr = multicast.recv.endSocket(multicast.recv.genSocket()) + >>> temp_fxtr is None + True + >>> + + + """ + if not (sock is None): + try: + sock.shutdown(socket.SHUT_RD) + sock.close() + except OSError: + sock = None + return None + + def parseArgs(arguments=None): """Parses the CLI arguments. See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.recv is not None + True + >>> + + Testcase 0: parseArgs should return a namespace. + A: Test that the multicast component is initialized. + B: Test that the recv component is initialized. + C: Test that the recv.parseArgs component is initialized. + + >>> multicast.recv is not None + True + >>> multicast.recv.parseArgs is not None + True + >>> tst_fxtr_args = ['''--port=1234''', '''--iface=127.0.0.1'''] + >>> test_fixture = multicast.recv.parseArgs(tst_fxtr_args) + >>> test_fixture is not None + True + >>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + <...Namespace...> + >>> + + """ - __epilog__ = """- WIP -""" - __description__ = """Python Multicast Reciver.""" parser = argparse.ArgumentParser( prog=__proc__, - description=__description__, - epilog=__epilog__, - exit_on_error=False + description=__prolog__, + epilog=__epilog__ ) - parser.add_argument("""--port""", type=int, default=__MCAST_DEFAULT_PORT) + parser.add_argument('--port', type=int, default=__MCAST_DEFAULT_PORT) parser.add_argument( '--join-mcast-groups', default=[], nargs='*', - help="""multicast groups (ip addrs) to listen to join""" + help="""multicast groups (ip addrs) to listen to join.""" ) + __tmp_help = """local interface to use for listening to multicast data; """ + __tmp_help += """if unspecified, any one interface may be chosen.""" parser.add_argument( '--iface', default=None, - help=str("""local interface to use for listening to multicast data; """).join( - """if unspecified, any one interface may be chosen""" - ) + help=str(__tmp_help) ) __tmp_help = """multicast groups (ip addrs) to bind to for the udp socket; """ __tmp_help += """should be one of the multicast groups joined globally """ @@ -146,21 +247,14 @@ def parseArgs(arguments=None): return parser.parse_args(arguments) -def run(groups, port, iface=None, bind_group=None): - """The work-horse function. Spawns a listener for multicast based on arguments. - generally speaking you want to bind to one of the groups you joined in - this module/instance, but it is also possible to bind to group which - is added by some other programs (like another python program instance of this) +def hearstep(groups, port, iface=None, bind_group=None): """ - - # assert bind_group in groups + [None], \ - # 'bind group not in groups to join' - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - - # allow reuse of socket (to allow another instance of python running this - # script binding to the same ip/port) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - + The work-horse function. + """ + if groups is None: + groups = [] + sock = genSocket() + msgbuffer = str("""""") try: sock.bind(('' if bind_group is None else bind_group, port)) for group in groups: @@ -170,20 +264,25 @@ def run(groups, port, iface=None, bind_group=None): socket.INADDR_ANY if iface is None else socket.inet_aton(iface) ) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - + chunk = None while True: - print(sock.recv(1316)) + chunk = sock.recv(1316) + if chunk is not None: + msgbuffer += str(chunk, encoding='utf8') + chunk = None + msgbuffer += unicodedata.lookup("""SOFT HYPHEN""") + #print(sock.recv(1316)) # about 969 bytes in base64 encoded as chars except KeyboardInterrupt: - print("") - print(str("""Closing""")) + print("""""") + print(str("""User Interrupted""")) + except OSError: + print(str("""""")) finally: - try: - sock.shutdown(socket.SHUT_RD) - sock.close() - except OSError: - False - sock = None + sock = endSocket(sock) + print(str("""""")) + print(str(msgbuffer)) + #return msgbuffer def main(*argv): @@ -194,11 +293,12 @@ def main(*argv): Regardles of errors the result as an 'exit code' (int) is returned. (Note the __main__ handler just exits with this code as a true return code status.) + """ __exit_code = 0 try: args = parseArgs(*argv) - run(args.join_mcast_groups, int(args.port), args.iface, args.bind_group) + hearstep(args.join_mcast_groups, int(args.port), args.iface, args.bind_group) except argparse.ArgumentError: print('Input has an Argument Error') __exit_code = 2 @@ -208,8 +308,57 @@ def main(*argv): return __exit_code -if __name__ == '__main__': - __exit_code = 2 - if (sys.argv is not None) and (len(sys.argv) >= 1): - __exit_code = main(sys.argv[1:]) - exit(__exit_code) +__doc__ = __prolog__ + """ + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + Testcase 0: Multicast should be importable. + + >>> import multicast + >>> + >>> multicast.__doc__ is not None + True + >>> + + Testcase 1: Recv should be automaticly imported. + A: Test that the multicast component is initialized. + B: Test that the recv component is initialized. + C: Test that the recv component has __doc__ + + >>> multicast is not None + True + >>> multicast.recv is not None + True + >>> multicast.recv.__doc__ is not None + True + >>> type(multicast.recv.__doc__) == type(str('''''')) + True + >>> + + Testcase 2: Recv should be detailed with some metadata. + A: Test that the __MAGIC__ variables are initialized. + B: Test that the __MAGIC__ variables are strings. + + >>> multicast.recv is not None + True + >>> multicast.recv.__module__ is not None + True + >>> type(multicast.recv.__doc__) == type(multicast.recv.__module__) + True + >>> multicast.recv.__prolog__ is not None + True + >>> type(multicast.recv.__doc__) == type(multicast.recv.__prolog__) + True + >>> multicast.recv.__epilog__ is not None + True + >>> type(multicast.recv.__doc__) == type(multicast.recv.__epilog__) + True + >>> type(multicast.recv.__doc__) == type(multicast.recv.__proc__) + True + >>> + + +""" + __epilog__ + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ + diff --git a/multicast/send.py b/multicast/send.py index 58872862..f9b9a3ff 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -30,7 +30,7 @@ # .......................................... # NO ASSOCIATION -__all__ = ["""main""", """run""", """parseArgs""", """__module__""", """__name__""", """__doc__"""] +__all__ = ["""main""", """saystep""", """parseArgs""", """__module__""", """__name__""", """__doc__"""] __package__ = """multicast""" @@ -68,8 +68,8 @@ B: Test that the send component is initialized. >>> import multicast + >>> import multicast.__main__ >>> - >>> multicast.__main__ is not None True >>> multicast.send is not None @@ -113,14 +113,41 @@ def parseArgs(*arguments): """Parses the CLI arguments. See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.send is not None + True + >>> + + Testcase 0: parseArgs should return a namespace. + A: Test that the multicast component is initialized. + B: Test that the send component is initialized. + C: Test that the send.parseArgs component is initialized. + + >>> multicast.send is not None + True + >>> multicast.send.parseArgs is not None + True + >>> tst_fxtr_args = ['''--port=1234''', '''--mesage''', '''is required'''] + >>> test_fixture = multicast.send.parseArgs(tst_fxtr_args) + >>> test_fixture is not None + True + >>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + <...Namespace...> + >>> + + """ __epilog__ = """- WIP -""" __description__ = """Python Multicast Broadcaster.""" parser = argparse.ArgumentParser( prog=__proc__, description=__description__, - epilog=__epilog__, - exit_on_error=False + epilog=__epilog__ ) parser.add_argument("""--port""", type=int, default=__MCAST_DEFAULT_PORT) parser.add_argument('--mcast-group', default='224.1.1.1') @@ -131,7 +158,8 @@ def parseArgs(*arguments): return parser.parse_args(*arguments) -def run(group, port, data): +def saystep(group, port, data): + """The actual magic is handeled here.""" MULTICAST_TTL = 20 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) try: @@ -150,7 +178,7 @@ def main(*argv): __exit_code = 1 try: args = parseArgs(*argv) - run(args.mcast_group, int(args.port), args.message) + saystep(args.mcast_group, int(args.port), args.message) __exit_code = 0 except argparse.ArgumentError: print('Input has an Argument Error') @@ -160,9 +188,3 @@ def main(*argv): __exit_code = 3 return __exit_code - -if __name__ == '__main__': - __exit_code = 2 - if (sys.argv is not None) and (len(sys.argv) >= 1): - __exit_code = main(sys.argv[1:]) - exit(__exit_code) diff --git a/setup.cfg b/setup.cfg index 9cc0f530..2f2fa061 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,30 +4,22 @@ version = 1.2.0 author = Mr. Walls author_email = reactive-firewall@users.noreply.github.com summary = Python multicast repo for send/recv stubs -description_file = file: README.md +description_file = README.md long_description = file: README.md long_description_content_type = text/markdown home_page = https://github.com/reactive-firewall/multicast download_url = https://github.com/reactive-firewall/multicast.git -license = file: LICENSE.md -classifiers = - License :: OSI Approved :: MIT License - Development Status :: 4 - Beta - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.7 +license = MIT +license_file = LICENSE.md [bdist_rpm] -url = https://www.github.com/reactive-firewall/multicast.git +url = https://github.com/reactive-firewall/multicast.git [bdist_wheel] universal=1 [files] -packages = multicast +packages = find:*.py [options] py_modules = multicast @@ -39,4 +31,3 @@ scripts = [options.packages.find] exclude = tests - diff --git a/setup.py b/setup.py index db19b9d2..1d6ea7d7 100755 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ from setuptools import setup from setuptools import find_packages except Exception: - raise NotImplementedError("""Not Implemented.""") + raise ImportError("""Not Implemented.""") def readFile(filename): @@ -46,15 +46,34 @@ def readFile(filename): readme = readFile("""README.md""") SLA = readFile("""LICENSE.md""") +try: + class_tags = [ + str("""Development Status :: 4 - Beta"""), + str("""Operating System :: POSIX :: Linux"""), + str("""License :: OSI Approved :: MIT License"""), + str("""Programming Language :: Python"""), + str("""Programming Language :: Python :: 3.9"""), + str("""Programming Language :: Python :: 3.8"""), + str("""Programming Language :: Python :: 3.7"""), + str("""Topic :: Network""") + ] +except Exception: + class_tags = str("""Development Status :: 4 - Beta""") + + setup( name="""multicast""", - version="""1.2.0""", + version="""1.3.0""", description="""Python Multicast Repo for Send/Recv Stubs""", long_description=readme, + long_description_content_type="""text/markdown""", + zip_safe=False, + include_package_data=True, install_requires=requirements, author="""reactive-firewall""", author_email="""reactive-firewall@users.noreply.github.com""", + classifiers=class_tags, url="""https://github.com/reactive-firewall/multicast.git""", license=SLA, - packages=find_packages(exclude=("""tests""")), + packages=find_packages(exclude=("""tests""", """docs""")), ) From a2abf29d0c80bd740ad2e192c4ef07cdc1020e1b Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 25 Jan 2022 03:09:53 -0800 Subject: [PATCH 075/135] [REGRESSION] improved style as per linters --- multicast/__main__.py | 24 ++++++++++++++++++++---- multicast/recv.py | 19 +++++++++++-------- multicast/send.py | 33 ++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/multicast/__main__.py b/multicast/__main__.py index 3d8f1b36..633ebca5 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -17,20 +17,35 @@ # See the License for the specific language governing permissions and # limitations under the License. -__all__ = ["""__module__""", """__prog__""", """__prolog__""", """__epilog__""", """__doc__""", "NoOp", """SendMCast""", """joinMCast""", """dumpUsage""", """TASK_OPTIONS""", """__checkToolArgs""", """buildArgs""", """main""", """parseArgs""", """useTool"""] +__all__ = [ + """__module__""", """__prog__""", """__prolog__""", """__epilog__""", + """__doc__""", "NoOp", """SendMCast""", """joinMCast""", + """dumpUsage""", """TASK_OPTIONS""", """__checkToolArgs""", + """buildArgs""", """main""", """parseArgs""", """useTool""" +] + __package__ = """multicast""" + __module__ = """multicast.__main__""" + __file__ = """multicast/__main__.py""" -__prog__ = """multicast""" + +__name__ = """multicast.__main__""" + + +__proc__ = """multicast""" + __prolog__ = """The Main Entrypoint""" + __epilog__ = """Add an epilog here.""" + __doc__ = __prolog__ + """ Minimal Acceptance Testing: @@ -59,6 +74,7 @@ """ + try: import sys import argparse @@ -276,7 +292,7 @@ def main(*argv): if __name__ in u'__main__': __EXIT_CODE = 2 if (sys.argv is not None) and (len(sys.argv) > 1): - __EXIT_CODE = main(sys.argv[1:]) + __EXIT_CODE = main(argv=sys.argv) else: - __EXIT_CODE = main(argv=["""--help"""]) + __EXIT_CODE = main(argv=[__proc__, """--help"""]) exit(__EXIT_CODE) diff --git a/multicast/recv.py b/multicast/recv.py index 58f23480..0e3026e9 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -30,7 +30,11 @@ # .......................................... # NO ASSOCIATION -__all__ = ["""genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", """__module__""", """__name__""", """__proc__""", """__prolog__""", """__epilog__""", """__doc__"""] +__all__ = [ + """genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", + """__module__""", """__name__""", """__proc__""", """__prolog__""", + """__epilog__""", """__doc__""" +] __package__ = """multicast""" @@ -90,7 +94,7 @@ def genSocket(): """Generates an unbound socket.socket object ready to receive network traffic. - + Minimal Acceptance Testing: First setup test fixtures by importing multicast. @@ -270,8 +274,7 @@ def hearstep(groups, port, iface=None, bind_group=None): if chunk is not None: msgbuffer += str(chunk, encoding='utf8') chunk = None - msgbuffer += unicodedata.lookup("""SOFT HYPHEN""") - #print(sock.recv(1316)) + # msgbuffer += unicodedata.lookup("""SOFT HYPHEN""") # about 969 bytes in base64 encoded as chars except KeyboardInterrupt: print("""""") @@ -280,16 +283,16 @@ def hearstep(groups, port, iface=None, bind_group=None): print(str("""""")) finally: sock = endSocket(sock) - print(str("""""")) - print(str(msgbuffer)) - #return msgbuffer + # print(str("""""")) + # print(str(msgbuffer)) + return msgbuffer def main(*argv): """The Main Event. This does two things: 1: calls parseArgs() and passes the given arguments, handling any errors if needed. - 2: calls run with the parsed args if able and handles any errors regardles + 2: calls hearstep with the parsed args if able and handles any errors regardles Regardles of errors the result as an 'exit code' (int) is returned. (Note the __main__ handler just exits with this code as a true return code status.) diff --git a/multicast/send.py b/multicast/send.py index f9b9a3ff..307af09b 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -30,7 +30,10 @@ # .......................................... # NO ASSOCIATION -__all__ = ["""main""", """saystep""", """parseArgs""", """__module__""", """__name__""", """__doc__"""] +__all__ = [ + """main""", """saystep""", """parseArgs""", + """__module__""", """__name__""", """__doc__""" +] __package__ = """multicast""" @@ -56,25 +59,25 @@ Testcase 0: Multicast should be importable. - >>> import multicast - >>> + >>> import multicast + >>> - >>> multicast.__doc__ is not None - True - >>> + >>> multicast.__doc__ is not None + True + >>> Testcase 1: Recv should be automaticly imported. A: Test that the __main__ component is initialized. B: Test that the send component is initialized. - >>> import multicast - >>> import multicast.__main__ - >>> - >>> multicast.__main__ is not None - True - >>> multicast.send is not None - True - >>> + >>> import multicast + >>> import multicast.__main__ + >>> + >>> multicast.__main__ is not None + True + >>> multicast.send is not None + True + >>> """ @@ -113,7 +116,7 @@ def parseArgs(*arguments): """Parses the CLI arguments. See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs. - + Minimal Acceptance Testing: First setup test fixtures by importing multicast. From bd10f1e92341ca8aaeba9ee1d6ef70237cabc4dd Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 25 Jan 2022 23:48:30 -0800 Subject: [PATCH 076/135] [REGRESSION] fix for #12 --- multicast/__main__.py | 27 +++++++++++++++------------ tests/test_usage.py | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/multicast/__main__.py b/multicast/__main__.py index 633ebca5..b1232c9f 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -18,10 +18,10 @@ # limitations under the License. __all__ = [ - """__module__""", """__prog__""", """__prolog__""", """__epilog__""", - """__doc__""", "NoOp", """SendMCast""", """joinMCast""", - """dumpUsage""", """TASK_OPTIONS""", """__checkToolArgs""", - """buildArgs""", """main""", """parseArgs""", """useTool""" + """__module__""", """__proc__""", """__prolog__""", """__epilog__""", + """__doc__""", """NoOp""", """SendMCast""", """joinMCast""", + """dumpUsage""", """__checkToolArgs""", """buildArgs""", + """TASK_OPTIONS""", """parseArgs""", """useTool""", """main""" ] @@ -34,7 +34,7 @@ __file__ = """multicast/__main__.py""" -__name__ = """multicast.__main__""" +# __name__ = """multicast.__main__""" __proc__ = """multicast""" @@ -72,7 +72,8 @@ True >>> - """ + +""" try: @@ -164,7 +165,8 @@ def joinMCast(*args, **kwargs): def dumpUsage(*args, **kwargs): """Prints help usage""" - return buildArgs().print_help() + buildArgs().print_help() + return None # More boiler-plate-code @@ -184,7 +186,7 @@ def buildArgs(): returns argparse.ArgumentParser - the ArgumentParser to use. """ parser = argparse.ArgumentParser( - prog=__prog__, + prog=__proc__, description=__prolog__, epilog=__epilog__, add_help=False @@ -199,7 +201,7 @@ def buildArgs(): ) parser.add_argument( 'some_task', nargs='?', choices=TASK_OPTIONS.keys(), - help='the help text for this option.' + help='the action and any action arguments to pass.' ) return parser @@ -246,6 +248,7 @@ def __checkToolArgs(args): True >>> + """ if args is None: args = [None] @@ -267,7 +270,7 @@ def useTool(tool, *arguments): def main(*argv): """The Main Event.""" - __EXIT_CODE = 0 + __EXIT_CODE = 1 try: try: args, extra = parseArgs(*argv) @@ -292,7 +295,7 @@ def main(*argv): if __name__ in u'__main__': __EXIT_CODE = 2 if (sys.argv is not None) and (len(sys.argv) > 1): - __EXIT_CODE = main(argv=sys.argv) + __EXIT_CODE = main(sys.argv[1:]) else: - __EXIT_CODE = main(argv=[__proc__, """--help"""]) + __EXIT_CODE = main([str(__proc__), """-h"""]) exit(__EXIT_CODE) diff --git a/tests/test_usage.py b/tests/test_usage.py index 46d7e5ec..6b8505ea 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -35,7 +35,7 @@ if context.__name__ is None: raise ImportError("[CWE-758] Failed to import context") else: - from context import multicast + from context import multicast as multicast from context import unittest as unittest from context import subprocess as subprocess except Exception: From ef2f24b4027e219e1931550fbf78b36dddf69d27 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 26 Jan 2022 01:49:25 -0800 Subject: [PATCH 077/135] [REGRESSION] fix for #6 --- tests/check_cc_line.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/check_cc_line.bash b/tests/check_cc_line.bash index b9c2326a..b0538a23 100755 --- a/tests/check_cc_line.bash +++ b/tests/check_cc_line.bash @@ -73,7 +73,8 @@ if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 + # SC2173 - https://github.com/koalaman/shellcheck/wiki/SC2173 + # trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 @@ -88,7 +89,6 @@ fi # THIS IS THE ACTUAL TEST _TEST_ROOT_DIR="./" ; if [[ -d ./multicast ]] ; then - _TEST_ROOT_DIR="./multicast" ; _TEST_ROOT_DIR="./" ; elif [[ -d ./tests ]] ; then _TEST_ROOT_DIR="./" ; From 264843bd0eb01d6ded559442b34d72730adc4b93 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 30 Jan 2022 22:44:12 -0800 Subject: [PATCH 078/135] [TESTS] added integration test attempt (unstable) --- tests/test_usage.py | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/test_usage.py b/tests/test_usage.py index a4c4d715..9580a33d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -40,6 +40,7 @@ from context import os as os from context import subprocess as subprocess from context import profiling as profiling + from multiprocessing import Process except Exception: raise ImportError("[CWE-758] Failed to import test context") @@ -118,6 +119,40 @@ def test_multicast_help_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) + def test_multicast_message_send_recv(self): + """Tests the basic send and recv test""" + theResult = False + fail_fixture = str("""SAY --> HEAR == error""") + try: + _fixture_SAY_args = [ + """--port=19991""", + """--mcast-group='224.0.0.1'""", + """--message='test'""" + ] + _fixture_HEAR_args = [ + """--port=19991""", + """--join-mcast-groups='224.0.0.1'""", + """--bind-group='224.0.0.1'""" + ] + p = Process(target=multicast.__main__.useTool, name="HEAR", args=("HEAR", _fixture_HEAR_args,)) + p.start() + try: + self.assertIsNotNone(multicast.__main__.useTool("SAY", _fixture_SAY_args)) + self.assertIsNotNone(multicast.__main__.useTool("SAY", _fixture_SAY_args)) + self.assertIsNotNone(multicast.__main__.useTool("SAY", _fixture_SAY_args)) + except Exception: + p.join() + raise unittest.SkipTest(fail_fixture) + p.join() + self.assertIsNotNone(p.exitcode) + theResult = True + except Exception as err: + context.debugtestError(err) + #raise unittest.SkipTest(fail_fixture) + self.fail(fail_fixture) + theResult = False + self.assertTrue(theResult, fail_fixture) + def debugIfNoneResult(thepython, theArgs, theOutput): """In case you need it.""" @@ -228,6 +263,38 @@ def test_version_has_value_case(self): theResult = False self.assertTrue(theResult, str("""Could Not find version from multicast --version""")) + def test_run_lib_command_help(self): + """Test case for multicast* --help.""" + theResult = False + fail_fixture = str("""multicast --help == not helpful""") + try: + if (self._thepython is not None): + for test_case in [".__main__", ""]: + args = [ + str(self._thepython), + str("-m"), + str("multicast{}").format( + str( + test_case + ) + ), + str("--help") + ] + theOutputtext = context.checkPythonCommand(args, stderr=subprocess.STDOUT) + self.assertIn(str("usage:"), str(theOutputtext)) + if (str("usage:") in str(theOutputtext)): + theResult = True + else: + theResult = False + context.debugUnexpectedOutput(str("usage:"), str(theOutputtext), self._thepython) + except Exception as err: + context.debugtestError(err) + err = None + del err + self.fail(fail_fixture) + theResult = False + self.assertTrue(theResult, str("""Could Not find usage from multicast --help""")) + def test_profile_template_case(self): """Test case template for profiling""" theResult = False From 4c0551e03f257a11326627ad5696fe025f24fe9e Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 30 Jan 2022 23:09:26 -0800 Subject: [PATCH 079/135] [REGRESSION] minor fix for regression in style --- tests/test_usage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_usage.py b/tests/test_usage.py index f07f5746..98b52e7d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -163,7 +163,7 @@ def test_multicast_message_send_recv(self): theResult = True except Exception as err: context.debugtestError(err) - #raise unittest.SkipTest(fail_fixture) + # raise unittest.SkipTest(fail_fixture) self.fail(fail_fixture) theResult = False self.assertTrue(theResult, fail_fixture) From 09086108f4d45dfb766ea1dedb4be629eff93619 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 30 Jan 2022 23:52:17 -0800 Subject: [PATCH 080/135] [TESTS] slight improvement for test utilities by refactor --- tests/context.py | 66 ++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/tests/context.py b/tests/context.py index 812cf936..ef1cc8ea 100644 --- a/tests/context.py +++ b/tests/context.py @@ -112,14 +112,14 @@ def getCoverageCommand(): First setup test fixtures by importing test context. - >>> import tests.context - >>> + >>> import tests.context + >>> Testcase 1: function should have a output. - >>> tests.context.getCoverageCommand() is not None - True - >>> + >>> tests.context.getCoverageCommand() is not None + True + >>> """ @@ -139,14 +139,31 @@ def getCoverageCommand(): def __check_cov_before_py(): """ - Utility Function to check for coverage before just python. + Utility Function to check for coverage availability before just using plain python. + Rather than just return the sys.executable which will usually be a python implementation, + this function will search for a coverage tool before falling back on just plain python. + + Meta Testing: + + First setup test fixtures by importing test context. + + >>> import tests.context + >>> + + Testcase 1: function should have a output. + + >>> tests.context.__check_cov_before_py() is not None + True + >>> + + """ thepython = str(sys.executable) thecov = getCoverageCommand() - if (sys.version_info >= (3, 3)): - if (str("coverage") in str(thecov)) and (sys.version_info >= (3, 3)): - thecov += str(" run -p") - elif (str("coverage") in str(thecov)) and (sys.version_info <= (3, 2)): + if (str("coverage") in str(thecov)) and (sys.version_info >= (3, 7)): + thecov += str(" run -p") + thepython = str("{} -m {}").format(str(sys.executable), str(thecov)) + else: try: import coverage if coverage.__name__ is not None: @@ -192,25 +209,19 @@ def checkCovCommand(args=[None]): """Utility Function.""" if sys.__name__ is None: raise ImportError("[CWE-758] Failed to import system. WTF?!!") - if str("{} -m coverage ").format(str(sys.executable)) in str(args[0]): - args[0] = str(sys.executable) - args.insert(1, str("-m")) - args.insert(2, str("coverage")) - args.insert(3, str("run")) - args.insert(4, str("-p")) - args.insert(5, str("--source=multicast")) - elif str("{} -m coverage3 ").format(str(sys.executable)) in str(args[0]): + if str("{} -m coverage").format(str(sys.executable)) in str(args[0]): args[0] = str(sys.executable) args.insert(1, str("-m")) - args.insert(2, str("coverage3")) - args.insert(3, str("run")) - args.insert(4, str("-p")) - args.insert(5, str("--source=multicast")) + if str("{} -m coverage3 ").format(str(sys.executable)) in str(args[0]): + args.insert(2, str("coverage3")) + else: + args.insert(2, str("coverage")) + i = 2 else: - args[0] = str("coverage") - args.insert(1, str("run")) - args.insert(2, str("-p")) - args.insert(3, str("--source=multicast")) + i = 0 + args.insert(i+1, str("run")) + args.insert(i+2, str("-p")) + args.insert(i+3, str("--source=multicast")) return args @@ -275,8 +286,7 @@ def checkPythonFuzzing(args=[None], stderr=None): args.insert(2, str("-p")) args.insert(2, str("--source=multicast")) theOutput = subprocess.check_output(args, stderr=stderr) - if isinstance(theOutput, bytes): - theOutput = theOutput.decode('utf_8') + theOutput = checkStrOrByte(theOutput) except Exception as err: theOutput = None raise RuntimeError(err) From 5ecbfac65bd7ca041ce918d1b5cfa8e19df16857 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 31 Jan 2022 04:28:29 -0800 Subject: [PATCH 081/135] [TESTS] WIP #17 - ( Closes #15 ) --- .coveragerc | 2 ++ Makefile | 2 +- tests/__init__.py | 30 ++++++++++++++++++++++ tests/check_codecov | 22 +++++++++-------- tests/check_spelling | 3 ++- tests/context.py | 59 ++++++++++++++++++++------------------------ tests/test_usage.py | 2 ++ 7 files changed, 76 insertions(+), 44 deletions(-) diff --git a/.coveragerc b/.coveragerc index 335f068a..c34842d5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,7 @@ [run] parallel = True +branch = True +concurrency = multiprocessing [report] include = multicast*,tests* diff --git a/Makefile b/Makefile index 3633b675..f348a246 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --include=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL=exit 2 ; + $(QUIET)$(COVERAGE) run -p --include=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL="exit 2" ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); diff --git a/tests/__init__.py b/tests/__init__.py index ab6af0ea..28b2b357 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -20,6 +20,19 @@ __module__ = """tests""" +__doc__ = """Multicast Testing Module. + + Testing: + + Testcase 0: Load tests fixtures + + >>> import tests as _tests + >>> _tests.__module__ is not None + True + + +""" + try: import sys if sys.__name__ is None: # pragma: no branch @@ -121,6 +134,23 @@ def load_tests(loader, tests, pattern): + """ + Loads the tests from the project and then attempts to load the doctests too. + + Testing: + + Testcase 0: Load test fixtures + + >>> import tests as _tests + >>> + + Testcase 1: Load test fixtures + + >>> import tests as _tests + >>> _tests.load_tests is not None + True + + """ import doctest finder = doctest.DocTestFinder(verbose=True, recurse=True, exclude_empty=True) suite = unittest.TestSuite() diff --git a/tests/check_codecov b/tests/check_codecov index c679727d..06a5cf8a 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -62,6 +62,7 @@ ulimit -t 1200 PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${PATH}" +LANG=${LANG:-"en_US"} LC_ALL="${LANG:1:5}.utf-8" umask 027 @@ -72,6 +73,13 @@ test -x $(command -v grep) || exit 126 ; test -x $(command -v curl) || exit 126 ; test -x $(command -v shasum) || exit 126 ; +# sorry no windows support here +if [[ $( \uname -s ) == "Darwin" ]] ; then + CI_OS="macos" +else + CI_OS="linux" +fi + function cleanup() { rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; rm -f ./codecov 2>/dev/null || true ; wait ; @@ -81,7 +89,8 @@ if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then trap 'cleanup ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 trap 'cleanup ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 trap 'cleanup ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 - trap 'cleanup ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 + # SC2173 - https://github.com/koalaman/shellcheck/wiki/SC2173 + # trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 trap 'cleanup ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 trap 'cleanup ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 trap 'cleanup ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 @@ -96,7 +105,6 @@ fi # THIS IS THE ACTUAL TEST DIR USED (update _TEST_ROOT_DIR as needed) _TEST_ROOT_DIR="./" ; if [[ -d ./multicast ]] ; then - _TEST_ROOT_DIR="./multicast" ; _TEST_ROOT_DIR="./" ; elif [[ -d ./tests ]] ; then _TEST_ROOT_DIR="./" ; @@ -111,18 +119,12 @@ if [[ ( -r ./codecov_env ) ]] ; then fi if [[ ( -r ./codecov.yml ) ]] ; then - cat codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 + cat codecov.yml | curl -X POST --data-binary @- https://codecov.io/validate 2>/dev/null || EXIT_CODE=6 fi if [[ ( -r ./.codecov.yml ) ]] ; then - cat ./.codecov.yml | curl --data-binary @- https://codecov.io/validate || EXIT_CODE=6 + cat ./.codecov.yml | curl -X POST --data-binary @- https://codecov.io/validate 2>/dev/null || EXIT_CODE=6 fi -# sorry no windows support here -if [[ $( \uname -s ) == "Darwin" ]] ; then - CI_OS="macos" -else - CI_OS="linux" -fi ######################### # actual Work starts here diff --git a/tests/check_spelling b/tests/check_spelling index 53747fa1..b39704c4 100755 --- a/tests/check_spelling +++ b/tests/check_spelling @@ -74,7 +74,8 @@ if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 + # SC2173 - https://github.com/koalaman/shellcheck/wiki/SC2173 + # trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 diff --git a/tests/context.py b/tests/context.py index ef1cc8ea..0673bd3e 100644 --- a/tests/context.py +++ b/tests/context.py @@ -112,13 +112,14 @@ def getCoverageCommand(): First setup test fixtures by importing test context. - >>> import tests.context + >>> import tests.context as context >>> Testcase 1: function should have a output. - >>> tests.context.getCoverageCommand() is not None - True + >>> import tests.context as context + >>> context.getCoverageCommand() is None + False >>> @@ -156,21 +157,29 @@ def __check_cov_before_py(): True >>> + Testcase 2: function should have a string output of python or coverage. + + >>> _test_fixture = tests.context.__check_cov_before_py() + >>> isinstance(_test_fixture, type(str(""))) + True + >>> (str("python") in _test_fixture) or (str("coverage") in _test_fixture) + True + >>> + """ thepython = str(sys.executable) thecov = getCoverageCommand() if (str("coverage") in str(thecov)) and (sys.version_info >= (3, 7)): - thecov += str(" run -p") - thepython = str("{} -m {}").format(str(sys.executable), str(thecov)) + thepython = str("{} run -p").format(str(thecov)) else: try: - import coverage + import coverage as coverage if coverage.__name__ is not None: thepython = str("{} -m coverage run -p").format(str(sys.executable)) except Exception: thepython = str(sys.executable) - return thepython + return str(thepython) def getPythonCommand(): @@ -193,7 +202,7 @@ def getPythonCommand(): >>> """ - thepython = "exit 1 ; #" + thepython = "python" try: thepython = __check_cov_before_py() except Exception: @@ -209,19 +218,18 @@ def checkCovCommand(args=[None]): """Utility Function.""" if sys.__name__ is None: raise ImportError("[CWE-758] Failed to import system. WTF?!!") + if str("coverage") in args[0]: + i = 0 if str("{} -m coverage").format(str(sys.executable)) in str(args[0]): args[0] = str(sys.executable) args.insert(1, str("-m")) - if str("{} -m coverage3 ").format(str(sys.executable)) in str(args[0]): - args.insert(2, str("coverage3")) - else: - args.insert(2, str("coverage")) + args.insert(2, str("coverage")) i = 2 else: - i = 0 - args.insert(i+1, str("run")) - args.insert(i+2, str("-p")) - args.insert(i+3, str("--source=multicast")) + args[0] = str(getCoverageCommand()) + args.insert(i+1, str("run")) + args.insert(i+2, str("-p")) + args.insert(i+3, str("--source=multicast")) return args @@ -270,26 +278,13 @@ def checkPythonFuzzing(args=[None], stderr=None): if args is None or args is [None]: theOutput = subprocess.check_output(["exit 1 ; #"]) else: - if str("coverage ") in args[0]: - if sys.__name__ is None: - raise ImportError("Failed to import system. WTF?!!") - if str("{} -m coverage ").format(str(sys.executable)) in str(args[0]): - args[0] = str(sys.executable) - args.insert(1, str("-m")) - args.insert(2, str("coverage")) - args.insert(3, str("run")) - args.insert(4, str("-p")) - args.insert(4, str("--source=multicast")) - else: - args[0] = str("coverage") - args.insert(1, str("run")) - args.insert(2, str("-p")) - args.insert(2, str("--source=multicast")) + if str("coverage") in args[0]: + args = checkCovCommand(args) theOutput = subprocess.check_output(args, stderr=stderr) - theOutput = checkStrOrByte(theOutput) except Exception as err: theOutput = None raise RuntimeError(err) + theOutput = checkStrOrByte(theOutput) return theOutput diff --git a/tests/test_usage.py b/tests/test_usage.py index 98b52e7d..10a14923 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -185,6 +185,8 @@ def debugIfNoneResult(thepython, theArgs, theOutput): class BasicIntegrationTestSuite(context.BasicUsageTestSuite): """Basic functional test cases.""" + __module__ = """tests.test_usage""" + def setUp(self): super(self.__class__, self).setUp() if (self._thepython is None): From 0e483dc1e024e63e8a7e07e1dc7c4332fb443ede Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 31 Jan 2022 04:44:09 -0800 Subject: [PATCH 082/135] [STYLE] WIP #11 - Style fixes --- tests/__init__.py | 2 +- tests/context.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 28b2b357..0cdb1d6f 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -20,7 +20,7 @@ __module__ = """tests""" -__doc__ = """Multicast Testing Module. +__doc__ = """Multicast Testing Module. Testing: diff --git a/tests/context.py b/tests/context.py index 0673bd3e..9f941ba9 100644 --- a/tests/context.py +++ b/tests/context.py @@ -227,9 +227,9 @@ def checkCovCommand(args=[None]): i = 2 else: args[0] = str(getCoverageCommand()) - args.insert(i+1, str("run")) - args.insert(i+2, str("-p")) - args.insert(i+3, str("--source=multicast")) + args.insert(i + 1, str("run")) + args.insert(i + 2, str("-p")) + args.insert(i + 3, str("--source=multicast")) return args From bb516b40234fc1c146bd733ea6606af0b8d5a383 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 1 Feb 2022 03:17:32 -0800 Subject: [PATCH 083/135] [FIX] Closes #15 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f348a246..04f66cde 100644 --- a/Makefile +++ b/Makefile @@ -101,9 +101,9 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --include=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL="exit 2" ; + $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL="exit 2" ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true - $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true + $(QUIET)$(COVERAGE) report --source=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); $(QUIET)$(ECHO) "$@: Done." From d92362c212a46d225db5563984e127e48b47f4b3 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 11 Feb 2022 02:22:54 -0800 Subject: [PATCH 084/135] ### ChangeLog: Changes in file .coveragerc: branch = True --- .coveragerc | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/.coveragerc b/.coveragerc index c34842d5..0b6dbb56 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,20 +7,41 @@ concurrency = multiprocessing include = multicast*,tests* # Regexes for lines to exclude from consideration exclude_lines = - # Have to re-enable the standard pragma - pragma: no cover - except Exception - except BaseException: - # Don't complain if tests don't hit defensive assertion code: - raise AssertionError - raise NotImplementedError - raise ImportError - except unittest.SkipTest - except IOError - except OSError + # Have to re-enable the standard pragma + pragma: no cover + from . import + except Exception + except BaseException: + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + raise ImportError + except unittest.SkipTest + except subprocess.CalledProcessError + except IOError + except OSError + # don't complain about sys.modules + sys.modules + not in sys.modules: + # Don't complain if non-runnable code isn't run: + if __name__ in u'__main__': + if __name__ in '__main__': + if __sys_path__ not in sys.path: + os.abort() + exit(0) - # Don't complain if non-runnable code isn't run: - if __name__ in '__main__': +partial_branches = + # Have to re-enable the standard pragma rules + pragma: no branch + # Don't complain if non-runnable code isn't run: + if __name__ in u'__main__': + if __name__ in '__main__': + if __sys_path__ not in sys.path: + # not in sys.modules: + if context.__name__ is None: + if 'os' not in sys.modules: + if 'os.path' not in sys.modules: + if 'argparse' not in sys.modules: ignore_errors = True From fc611e4cb343f75930f7c553dc3dce46157642db Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 11 Feb 2022 02:25:24 -0800 Subject: [PATCH 085/135] [REGRESSION] commit message style fix Changes in file .yamllint.conf: New File --- .yamllint.conf | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .yamllint.conf diff --git a/.yamllint.conf b/.yamllint.conf new file mode 100644 index 00000000..c4724781 --- /dev/null +++ b/.yamllint.conf @@ -0,0 +1,9 @@ + +extends: default + +rules: + line-length: + max: 280 + level: warning + indentation: + indent-sequences: whatever \ No newline at end of file From 63a2209e949c66456020e78c0929e8c48c13710d Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 11 Feb 2022 03:18:24 -0800 Subject: [PATCH 086/135] [TESTS] Added another test for endSocket Changes in file multicast/recv.py: def endSocket(sock=None): --- multicast/recv.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/multicast/recv.py b/multicast/recv.py index 0e3026e9..13583748 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -178,6 +178,20 @@ def endSocket(sock=None): True >>> + Testcase 2: Recv should have endSocket() function that takes a socket.socket object or does nothing. + A: Test that the recv component has the function 'endSocket' (see testcase 1) + B: Test that the 'endSocket' function returns nothing + + >>> multicast.recv.endSocket is not None + True + >>> multicast.recv.endSocket #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + >>> type(multicast.recv.endSocket) + + >>> multicast.recv.endSocket(None) is None + True + >>> + """ if not (sock is None): From 1452df90c70f34f72e3231b97cd3de6f84629ecb Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 18 Feb 2022 05:33:05 -0800 Subject: [PATCH 087/135] Altered makefile to allow for buffered logs during CI-Testing Changes in file Makefile: purge: clean uninstall --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 04f66cde..2968a281 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL="exit 2" ; + $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --buffer --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --buffer --verbose -s ./tests -t ./ || DO_FAIL="exit 2" ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true $(QUIET)$(COVERAGE) report --source=multicast* 2>/dev/null || true $(QUIET)$(DO_FAIL); From fcc1e4d05f77472e2e5512117b7b55f4ba2f18a8 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 19 Feb 2022 05:56:06 -0800 Subject: [PATCH 088/135] [FIX] Fixed coverage reports' temp files cleanup across test runs --- Makefile | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 04f66cde..22119b65 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,10 @@ # limitations under the License. +ifeq "$(LC_CTYPE)" "" + LC_CTYPE="en_US.utf-8" +endif + ifeq "$(ECHO)" "" ECHO=echo endif @@ -34,12 +38,13 @@ ifeq "$(PYTHON)" "" endif ifeq "$(COVERAGE)" "" - ifeq "$(COVERAGE)" "" - COVERAGE=`command -v coverage` + ifeq "$(COVERAGE_TOOL)" "" + COVERAGE_TOOL=`command -v coverage` endif - ifeq "$(COVERAGE)" "" - COVERAGE=`command -v coverage3` + ifeq "$(COVERAGE_TOOL)" "" + COVERAGE_TOOL=`command -v coverage3` endif + COVERAGE=export LC_CTYPE="en_US.utf-8" ; "$(COVERAGE_TOOL)" endif ifeq "$(WAIT)" "" @@ -101,9 +106,9 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --verbose -s ./tests -t ./ 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ || DO_FAIL="exit 2" ; - $(QUIET)$(COVERAGE) combine 2>/dev/null || true - $(QUIET)$(COVERAGE) report --source=multicast* 2>/dev/null || true + $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --verbose -s ./tests -t ./ tests 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ tests || DO_FAIL="exit 2" ; + $(QUIET)$(COVERAGE) combine 2>/dev/null || true ; + $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true ; $(QUIET)$(DO_FAIL); $(QUIET)$(ECHO) "$@: Done." @@ -156,6 +161,7 @@ cleanup: clean: cleanup $(QUIET)rm -f test-results/junit.xml 2>/dev/null || true + $(QUIET)$(COVERAGE) erase || true $(QUIET)rm -Rfd ./build/ 2>/dev/null || true $(QUIET)$(MAKE) -s -C ./docs/ -f Makefile clean 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." From 4f13469e7d401991e7d5156bbbb495947eb6c947 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 19 Feb 2022 06:10:16 -0800 Subject: [PATCH 089/135] [MERGE] resolves merge conflicts in ./Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 22119b65..574fbd44 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --verbose -s ./tests -t ./ tests 2>/dev/null || $(PYTHON) -m unittest discover --verbose -s ./tests -t ./ tests || DO_FAIL="exit 2" ; + $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --buffer --verbose -s ./tests -t ./ tests 2>/dev/null || $(PYTHON) -m unittest discover --verbose --buffer -s ./tests -t ./ tests || DO_FAIL="exit 2" ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true ; $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true ; $(QUIET)$(DO_FAIL); From cf17559cb977e4126fcee4f3e6228024d462cfbc Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 19 Feb 2022 06:58:18 -0800 Subject: [PATCH 090/135] [REGRESSION] fix for typo in recv.py Changes in file multicast/recv.py: def endSocket(sock=None): --- multicast/recv.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/multicast/recv.py b/multicast/recv.py index 13583748..c5b511ef 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -178,7 +178,8 @@ def endSocket(sock=None): True >>> - Testcase 2: Recv should have endSocket() function that takes a socket.socket object or does nothing. + Testcase 2: Recv should have endSocket() function that takes a socket.socket object, + otherwise does nothing. A: Test that the recv component has the function 'endSocket' (see testcase 1) B: Test that the 'endSocket' function returns nothing From b7fae8187e42b6957c4bef05efac5eb9807e5ba1 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 20 Feb 2022 04:38:26 -0800 Subject: [PATCH 091/135] [STYLE] Cleaning up some of the repo - please ignore the churn --- .gitattributes | 2 + .gitignore | 10 ++++- Makefile | 112 +++++++++++++++++++++++++++---------------------- 3 files changed, 71 insertions(+), 53 deletions(-) diff --git a/.gitattributes b/.gitattributes index 039b93e5..9dd5936e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,8 @@ *.cfg text diff=config *.txt text *.py text working-tree-encoding=UTF-8 diff=python +*.pyc -text +multicast/*.py text working-tree-encoding=UTF-8 diff=python *.sh text *.bash text diff=shell *.ini text diff --git a/.gitignore b/.gitignore index 5d7e4e3b..fc0f2370 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # Byte-compiled / optimized / DLL files __pycache__/ +./*/__pycache__/* +./*/__pycache__/ *.py[cod] *$py.class *~ @@ -38,6 +40,8 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ +test-results/ +test-results/* .coverage .coverage.* .cache @@ -91,10 +95,12 @@ ENV/ # Rope project settings .ropeproject - -#Mac OSX files +# Mac OSX files .DS_Store */.DS_Store +.*/*/.DS_Store *.xcworkspace *.xcworkspace/* +*.xcodeproj +*.xcodeproj/* diff --git a/Makefile b/Makefile index 574fbd44..4e289c1a 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,8 @@ # See the License for the specific language governing permissions and # limitations under the License. - ifeq "$(LC_CTYPE)" "" - LC_CTYPE="en_US.utf-8" + LC_CTYPE="en_US.UTF-8" endif ifeq "$(ECHO)" "" @@ -34,17 +33,16 @@ ifeq "$(MAKE)" "" endif ifeq "$(PYTHON)" "" - PYTHON=export LC_CTYPE="en_US.utf-8" ; `command -v python3` -B + PYTHON=`command -v python3` -B endif ifeq "$(COVERAGE)" "" - ifeq "$(COVERAGE_TOOL)" "" - COVERAGE_TOOL=`command -v coverage` + ifeq "$(COVERAGE)" "" + COVERAGE=`command -v coverage` endif - ifeq "$(COVERAGE_TOOL)" "" - COVERAGE_TOOL=`command -v coverage3` + ifeq "$(COVERAGE)" "" + COVERAGE=`command -v coverage3` endif - COVERAGE=export LC_CTYPE="en_US.utf-8" ; "$(COVERAGE_TOOL)" endif ifeq "$(WAIT)" "" @@ -73,6 +71,13 @@ ifeq "$(DO_FAIL)" "" DO_FAIL=$(ECHO) "ok" endif +ifeq "$(RM)" "" + RM=`command -v rm` -f + ifeq "$(RMDIR)" "" + RMDIR=$(RM)Rd + endif +endif + PHONY: must_be_root cleanup build: @@ -94,28 +99,28 @@ uninstall: $(QUITE)$(WAIT) $(QUIET)$(ECHO) "$@: Done." -test-reports: - $(QUIET)mkdir test-reports 2>/dev/null >/dev/null || true ; - $(QUIET)$(ECHO) "$@: Done." - purge: clean uninstall $(QUIET)$(PYTHON) -m pip uninstall multicast && python -m pip uninstall multicast || true - $(QUIET)rm -Rfd ./build/ 2>/dev/null || true - $(QUIET)rm -Rfd ./.eggs/ 2>/dev/null || true - $(QUIET)rm -Rfd ./test-reports/ 2>/dev/null || true + $(QUIET)$(RMDIR) ./build/ 2>/dev/null || true + $(QUIET)$(RMDIR) ./.eggs/ 2>/dev/null || true + $(QUIET)$(RMDIR) ./test-reports/ 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." test: cleanup $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --buffer --verbose -s ./tests -t ./ tests 2>/dev/null || $(PYTHON) -m unittest discover --verbose --buffer -s ./tests -t ./ tests || DO_FAIL="exit 2" ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true ; $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true ; - $(QUIET)$(DO_FAIL); + $(QUIET)$(DO_FAIL) ; $(QUIET)$(ECHO) "$@: Done." test-tox: cleanup $(QUIET)tox -v -- || tail -n 500 .tox/py*/log/py*.log 2>/dev/null $(QUIET)$(ECHO) "$@: Done." +test-reports: + $(QUIET)mkdir test-reports 2>/dev/null >/dev/null || true ; + $(QUIET)$(ECHO) "$@: Done." + test-pytest: cleanup test-reports $(QUIET)$(PYTHON) -m pytest --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests || python -m pytest --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests ; wait ; $(QUIET)$(ECHO) "$@: Done." @@ -123,52 +128,57 @@ test-pytest: cleanup test-reports test-style: cleanup $(QUIET)flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini $(QUIET)tests/check_spelling 2>/dev/null || true + $(QUIET)tests/check_codecov 2>/dev/null || true $(QUIET)tests/check_cc_line.bash 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." cleanup: - $(QUIET)rm -f tests/*.pyc 2>/dev/null || true - $(QUIET)rm -f tests/*~ 2>/dev/null || true - $(QUIET)rm -Rfd tests/__pycache__ 2>/dev/null || true - $(QUIET)rm -f multicast/*.pyc 2>/dev/null || true - $(QUIET)rm -Rfd multicast/__pycache__ 2>/dev/null || true - $(QUIET)rm -Rfd multicast/*/__pycache__ 2>/dev/null || true - $(QUIET)rm -f multicast/*~ 2>/dev/null || true - $(QUIET)rm -f *.pyc 2>/dev/null || true - $(QUIET)rm -f multicast/*/*.pyc 2>/dev/null || true - $(QUIET)rm -f multicast/*/*~ 2>/dev/null || true - $(QUIET)rm -f *.DS_Store 2>/dev/null || true - $(QUIET)rm -f ./.DS_Store 2>/dev/null || true - $(QUIET)rm -Rfd .pytest_cache/ 2>/dev/null || true - $(QUIET)rm -Rfd .eggs 2>/dev/null || true - $(QUIET)rmdir ./test-reports/ 2>/dev/null || true - $(QUIET)rm -f multicast/*.DS_Store 2>/dev/null || true - $(QUIET)rm -f multicast/*/*.DS_Store 2>/dev/null || true - $(QUIET)rm -f multicast/.DS_Store 2>/dev/null || true - $(QUIET)rm -f multicast/*/.DS_Store 2>/dev/null || true - $(QUIET)rm -f tests/.DS_Store 2>/dev/null || true - $(QUIET)rm -f tests/*/.DS_Store 2>/dev/null || true - $(QUIET)rm -f multicast.egg-info/* 2>/dev/null || true - $(QUIET)rmdir multicast.egg-info 2>/dev/null || true - $(QUIET)rm -f ./*/*~ 2>/dev/null || true - $(QUIET)rm -f ./*~ 2>/dev/null || true - $(QUIET)coverage erase 2>/dev/null || true - $(QUIET)rm -f ./.coverage 2>/dev/null || true - $(QUIET)rm -f ./coverage*.xml 2>/dev/null || true - $(QUIET)rm -f ./sitecustomize.py 2>/dev/null || true - $(QUIET)rm -f ./.*~ 2>/dev/null || true - $(QUIET)rm -Rfd ./.tox/ 2>/dev/null || true + $(QUIET)$(COVERAGE) erase 2>/dev/null || true + $(QUIET)$(RM) tests/*.pyc 2>/dev/null || true + $(QUIET)$(RM) tests/*~ 2>/dev/null || true + $(QUIET)$(RM) tests/__pycache__/* 2>/dev/null || true + $(QUIET)$(RM) multicast/*.pyc 2>/dev/null || true + $(QUIET)$(RM) multicast/*~ 2>/dev/null || true + $(QUIET)$(RM) multicast//__pycache__/* 2>/dev/null || true + $(QUIET)$(RM) multicast/*/*.pyc 2>/dev/null || true + $(QUIET)$(RM) multicast/*/*~ 2>/dev/null || true + $(QUIET)$(RM) multicast/*.DS_Store 2>/dev/null || true + $(QUIET)$(RM) multicast/*/*.DS_Store 2>/dev/null || true + $(QUIET)$(RM) multicast/.DS_Store 2>/dev/null || true + $(QUIET)$(RM) multicast/*/.DS_Store 2>/dev/null || true + $(QUIET)$(RM) tests/.DS_Store 2>/dev/null || true + $(QUIET)$(RM) tests/*/.DS_Store 2>/dev/null || true + $(QUIET)$(RM) multicast.egg-info/* 2>/dev/null || true + $(QUIET)$(RM) ./*.pyc 2>/dev/null || true + $(QUIET)$(RM) ./.coverage 2>/dev/null || true + $(QUIET)$(RM) ./coverage*.xml 2>/dev/null || true + $(QUIET)$(RM) ./sitecustomize.py 2>/dev/null || true + $(QUIET)$(RM) ./.DS_Store 2>/dev/null || true + $(QUIET)$(RM) ./*/.DS_Store 2>/dev/null || true + $(QUIET)$(RM) ./*/*~ 2>/dev/null || true + $(QUIET)$(RM) ./.*/*~ 2>/dev/null || true + $(QUIET)$(RM) ./*~ 2>/dev/null || true + $(QUIET)$(RM) ./.*~ 2>/dev/null || true + $(QUIET)$(RMDIR) tests/__pycache__ 2>/dev/null || true + $(QUIET)$(RMDIR) multicast/__pycache__ 2>/dev/null || true + $(QUIET)$(RMDIR) multicast/*/__pycache__ 2>/dev/null || true + $(QUIET)$(RMDIR) multicast.egg-info 2>/dev/null || true + $(QUIET)$(RMDIR) .pytest_cache/ 2>/dev/null || true + $(QUIET)$(RMDIR) .eggs 2>/dev/null || true + $(QUIET)$(RMDIR) ./test-reports/ 2>/dev/null || true + $(QUIET)$(RMDIR) ./.tox/ 2>/dev/null || true + $(QUIET)$(WAIT) ; clean: cleanup - $(QUIET)rm -f test-results/junit.xml 2>/dev/null || true - $(QUIET)$(COVERAGE) erase || true - $(QUIET)rm -Rfd ./build/ 2>/dev/null || true + $(QUIET)$(RM) ./test-results/junit.xml 2>/dev/null || true + $(QUIET)$(RMDIR) ./test-results/ 2>/dev/null || true + $(QUIET)$(RMDIR) ./build/ 2>/dev/null || true $(QUIET)$(MAKE) -s -C ./docs/ -f Makefile clean 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." must_be_root: $(QUIET)runner=`whoami` ; \ - if test $$runner != "root" ; then echo "You are not root." ; exit 1 ; fi + if test $$runner != "root" ; then $(ECHO) "You are not root." ; exit 1 ; fi %: $(QUIET)$(ECHO) "No Rule Found For $@" ; $(WAIT) ; From 4354c2c38740bfcb52412453e688d830ab5b5cc1 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 20 Feb 2022 20:54:47 -0800 Subject: [PATCH 092/135] [REGRESION] fix for 'make clean' --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 4e289c1a..80a386f5 100644 --- a/Makefile +++ b/Makefile @@ -73,9 +73,10 @@ endif ifeq "$(RM)" "" RM=`command -v rm` -f - ifeq "$(RMDIR)" "" - RMDIR=$(RM)Rd - endif +endif + +ifeq "$(RMDIR)" "" + RMDIR=$(RM) -Rd endif PHONY: must_be_root cleanup @@ -139,7 +140,7 @@ cleanup: $(QUIET)$(RM) tests/__pycache__/* 2>/dev/null || true $(QUIET)$(RM) multicast/*.pyc 2>/dev/null || true $(QUIET)$(RM) multicast/*~ 2>/dev/null || true - $(QUIET)$(RM) multicast//__pycache__/* 2>/dev/null || true + $(QUIET)$(RM) multicast/__pycache__/* 2>/dev/null || true $(QUIET)$(RM) multicast/*/*.pyc 2>/dev/null || true $(QUIET)$(RM) multicast/*/*~ 2>/dev/null || true $(QUIET)$(RM) multicast/*.DS_Store 2>/dev/null || true From 71a909c89b0f8ff419b30cd623cba9437b456117 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 21 Feb 2022 01:40:24 -0800 Subject: [PATCH 093/135] [TESTS] refactor a bit of the testing names --- tests/__init__.py | 1 + tests/context.py | 59 ++++++++++++++++++++++++++++--------- tests/profiling.py | 4 +-- tests/test_basic.py | 24 ++++++++------- tests/test_usage.py | 71 +++++++++++++++++++++++---------------------- 5 files changed, 98 insertions(+), 61 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 0cdb1d6f..e4f3bdba 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -19,6 +19,7 @@ __module__ = """tests""" +__name__ = """tests""" __doc__ = """Multicast Testing Module. diff --git a/tests/context.py b/tests/context.py index 9f941ba9..3826e347 100644 --- a/tests/context.py +++ b/tests/context.py @@ -34,16 +34,16 @@ >>> from context import os as os >>> - >>> from context import unittest as unittest + >>> from context import unittest as _unittest >>> - >>> from context import subprocess as subprocess + >>> from context import subprocess as _subprocess >>> - >>> from context import multicast as multicast + >>> from context import multicast as _multicast >>> - >>> from context import profiling as profiling + >>> from context import profiling as _profiling >>> """ @@ -101,6 +101,32 @@ raise ImportError("[CWE-440] profiling Failed to import.") +__BLANK = str("""""") +""" + A literaly named variable to improve readability of code when using a blank string. + + Meta Testing: + + First setup test fixtures by importing test context. + + >>> import tests.context as _context + >>> + + Testcase 1: __BLANK should be a blank string. + + >>> import tests.context as _context + >>> _context.__BLANK is None + False + >>> isinstance(_context.__BLANK, type(str())) + True + >>> len(_context.__BLANK) == int(0) + True + >>> + + +""" + + def getCoverageCommand(): """ Function for backend coverage command. @@ -131,9 +157,9 @@ def getCoverageCommand(): thecov = str("coverage") elif str("/coverage3") in str(checkPythonCommand(["command", "-v", "coverage3"])): thecov = str("coverage3") - else: + else: # pragma: no branch thecov = "exit 1 ; #" - except Exception: + except Exception: # pragma: no branch thecov = "exit 1 ; #" return str(thecov) @@ -172,7 +198,7 @@ def __check_cov_before_py(): thecov = getCoverageCommand() if (str("coverage") in str(thecov)) and (sys.version_info >= (3, 7)): thepython = str("{} run -p").format(str(thecov)) - else: + else: # pragma: no branch try: import coverage as coverage if coverage.__name__ is not None: @@ -205,7 +231,7 @@ def getPythonCommand(): thepython = "python" try: thepython = __check_cov_before_py() - except Exception: + except Exception: # pragma: no branch thepython = "exit 1 ; #" try: thepython = str(sys.executable) @@ -216,16 +242,16 @@ def getPythonCommand(): def checkCovCommand(args=[None]): """Utility Function.""" - if sys.__name__ is None: + if sys.__name__ is None: # pragma: no branch raise ImportError("[CWE-758] Failed to import system. WTF?!!") if str("coverage") in args[0]: i = 0 - if str("{} -m coverage").format(str(sys.executable)) in str(args[0]): + if str("{} -m coverage").format(str(sys.executable)) in str(args[0]): # pragma: no branch args[0] = str(sys.executable) args.insert(1, str("-m")) args.insert(2, str("coverage")) i = 2 - else: + else: # pragma: no branch args[0] = str(getCoverageCommand()) args.insert(i + 1, str("run")) args.insert(i + 2, str("-p")) @@ -248,13 +274,13 @@ def checkPythonCommand(args=[None], stderr=None): """function for backend subprocess check_output command""" theOutput = None try: - if args is None or args is [None]: + if args is None or args is [None]: # pragma: no branch theOutput = subprocess.check_output(["exit 1 ; #"]) else: if str("coverage") in args[0]: args = checkCovCommand(args) theOutput = subprocess.check_output(args, stderr=stderr) - except Exception as err: + except Exception as err: # pragma: no branch theOutput = None try: if err.output is not None: @@ -498,6 +524,13 @@ def test_absolute_truth_and_meaning(self): assert True self.assertTrue(True, "Insanitty Test Failed") + def test_finds_python_WHEN_testing(self): + """Test case 0: Class Test-Fixture Meta Test.""" + self.test_absolute_truth_and_meaning() + if (self._thepython is None) and (len(self._thepython) <= 0): + self.fail(str("""No python cmd to test with!""")) + self.test_absolute_truth_and_meaning() + @classmethod def tearDownClass(cls): """Overides unittest.TestCase.tearDownClass(cls) to clean up thepython test fixture.""" diff --git a/tests/profiling.py b/tests/profiling.py index 687b9169..b3f93471 100644 --- a/tests/profiling.py +++ b/tests/profiling.py @@ -160,7 +160,7 @@ def profiled_func(*args, **kwargs): return profiled_func return inner -except ImportError: +except ImportError: # pragma: no branch def do_profile(follow=None): "Helpful if you accidentally leave in production!" if follow is None: @@ -178,7 +178,7 @@ def main(argv=None): raise NotImplementedError("CRITICAL - test profiling main() not implemented. yet?") -if __name__ in '__main__': +if __name__ in '__main__': # pragma: no branch exitcode = 3 try: exitcode = main(sys.argv[1:]) diff --git a/tests/test_basic.py b/tests/test_basic.py index f09edbed..76459fed 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -40,7 +40,7 @@ raise ImportError("[CWE-758] Failed to import context") else: from context import unittest as unittest -except Exception: +except Exception: # pragma: no branch raise ImportError("[CWE-758] Failed to import test context") @@ -54,13 +54,15 @@ def test_absolute_truth_and_meaning(self): """Insanitty Test 1: Because it only matters if we're not mad as hatters.""" assert True - def test_meta_test(self): + def test_Does_Pass_WHEN_Meta_Test(self): """Insanity Test 2: for unittests assertion.""" self.assertTrue(True) self.assertFalse(False) self.assertIsNone(None) + self.test_absolute_truth_and_meaning() + self.test_None_WHEN_Nothing() - def test_syntax(self): + def test_Does_Pass_WHEN_Using_Import_From_Syntax(self): """Test case 0: importing multicast.""" theResult = False try: @@ -73,10 +75,10 @@ def test_syntax(self): print(str(type(impErr))) print(str(impErr)) theResult = False - assert theResult + self.assertTrue(theResult) - def test_the_help_command(self): - """Test case 1: import for backend library.""" + def test_Error_WHEN_the_help_command_is_called(self): + """Test case 1: the --help options should error when called.""" theResult = False try: from .context import multicast @@ -90,9 +92,9 @@ def test_the_help_command(self): theResult = True except Exception: theResult = False - assert theResult + self.assertTrue(theResult) - def test_corner_case_example(self): + def test_IsNone_WHEN_given_corner_case_input(self): """Example Test case for bad input directly into function.""" theResult = False try: @@ -105,15 +107,15 @@ def test_corner_case_example(self): theResult = True except Exception: theResult = False - assert theResult + self.assertTrue(theResult) - def test_new_tests(self): + def test_None_WHEN_Nothing(self): """Try adding new tests.""" self.assertIsNone(None) # define new tests below @unittest.skipUnless(sys.platform.startswith("linux"), "This test example requires linux") - def test_this_linux_only(self): + def test_Skip_UNLESS_linux_only(self): """Linux is the test.""" self.assertTrue(sys.platform.startswith("linux")) diff --git a/tests/test_usage.py b/tests/test_usage.py index 10a14923..5f090a87 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -86,6 +86,7 @@ def test_multicast_hear_invalid_arg_main(self): self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--port", "test"])) self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 0) self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "test"]), 1) + self.assertNotEqual(multicast.__main__.useTool("HEAR", ["--port", "11911", "--group=None"]), 1) theResult = True except Exception as err: context.debugtestError(err) @@ -192,24 +193,24 @@ def setUp(self): if (self._thepython is None): self.skipTest(str("""No python cmd to test with!""")) - def test_run_lib_command_plain(self): + def test_prints_usage_WHEN_called_GIVEN_help_argument(self): """Test case for multicast.__main__ help.""" theResult = False fail_fixture = str("""multicast.__main__(--help) == not helpful""") try: if (self._thepython is not None): - theOutputtext = context.checkPythonCommand([ + theOutputtxt = context.checkPythonCommand([ str(self._thepython), str("-m"), str("multicast"), str("--help") ], stderr=subprocess.STDOUT) - self.assertIn(str("usage:"), str(theOutputtext)) - if (str("usage:") in str(theOutputtext)): + self.assertIn(str("usage:"), str(theOutputtxt)) + if (str("usage:") in str(theOutputtxt)): theResult = True else: theResult = False - context.debugUnexpectedOutput(str("usage:"), str(theOutputtext), self._thepython) + context.debugUnexpectedOutput(str("usage:"), str(theOutputtxt), self._thepython) except Exception as err: context.debugtestError(err) err = None @@ -218,7 +219,7 @@ def test_run_lib_command_plain(self): theResult = False self.assertTrue(theResult, str("""Could Not find usage from multicast --help""")) - def test_run_lib_command_main(self): + def test_equivilant_response_WHEN_absolute_vs_implicit(self): """Test case for multicast vs multicast.__main__""" theResult = False try: @@ -228,17 +229,17 @@ def test_run_lib_command_main(self): str("multicast.__main__") ], stderr=subprocess.STDOUT) self.assertIsNotNone(theExpectedText) - theOutputtext = context.checkPythonCommand([ + theOutputtxt = context.checkPythonCommand([ str(self._thepython), str("-m"), str("multicast") ], stderr=subprocess.STDOUT) - self.assertIn(str(theExpectedText), str(theOutputtext)) - if (str(theExpectedText) in str(theOutputtext)): + self.assertIn(str(theExpectedText), str(theOutputtxt)) + if (str(theExpectedText) in str(theOutputtxt)): theResult = True else: theResult = False - context.debugUnexpectedOutput(str(theExpectedText), str(theOutputtext), self._thepython) + context.debugUnexpectedOutput(str(theExpectedText), str(theOutputtxt), self._thepython) except BaseException as err: context.debugtestError(err) err = None @@ -246,7 +247,7 @@ def test_run_lib_command_main(self): theResult = False self.assertTrue(theResult, str("""Could Not swap multicast for multicast.__main__""")) - def test_version_has_value_case(self): + def test_prints_version_WHEN_called_GIVEN_version_argument(self): """Test for result from --version argument: python -m multicast.* --version """ theResult = False if (self._thepython is not None): @@ -262,17 +263,17 @@ def test_version_has_value_case(self): ), str("--version") ] - theOutputtext = context.checkPythonCommand(args, stderr=subprocess.STDOUT) + theOutputtxt = context.checkPythonCommand(args, stderr=subprocess.STDOUT) # now test it try: - if isinstance(theOutputtext, bytes): - theOutputtext = theOutputtext.decode('utf8') + if isinstance(theOutputtxt, bytes): + theOutputtxt = theOutputtxt.decode('utf8') except UnicodeDecodeError: - theOutputtext = str(repr(bytes(theOutputtext))) + theOutputtxt = str(repr(bytes(theOutputtxt))) # ADD REAL VERSION TEST HERE - theResult = debugIfNoneResult(self._thepython, args, theOutputtext) + theResult = debugIfNoneResult(self._thepython, args, theOutputtxt) # or simply: - self.assertIsNotNone(theOutputtext) + self.assertIsNotNone(theOutputtxt) except Exception as err: context.debugtestError(err) err = None @@ -280,7 +281,7 @@ def test_version_has_value_case(self): theResult = False self.assertTrue(theResult, str("""Could Not find version from multicast --version""")) - def test_run_lib_command_help(self): + def test_Usage_Error_WHEN_the_help_command_is_called(self): """Test case for multicast* --help.""" theResult = False fail_fixture = str("""multicast --help == not helpful""") @@ -297,13 +298,13 @@ def test_run_lib_command_help(self): ), str("--help") ] - theOutputtext = context.checkPythonCommand(args, stderr=subprocess.STDOUT) - self.assertIn(str("usage:"), str(theOutputtext)) - if (str("usage:") in str(theOutputtext)): + theOutputtxt = context.checkPythonCommand(args, stderr=subprocess.STDOUT) + self.assertIn(str("usage:"), str(theOutputtxt)) + if (str("usage:") in str(theOutputtxt)): theResult = True else: theResult = False - context.debugUnexpectedOutput(str("usage:"), str(theOutputtext), self._thepython) + context.debugUnexpectedOutput(str("usage:"), str(theOutputtxt), self._thepython) except Exception as err: context.debugtestError(err) err = None @@ -328,15 +329,15 @@ def test_profile_template_case(self): ) ) ] - theOutputtext = context.timePythonCommand(args, stderr=subprocess.STDOUT) + theOutputtxt = context.timePythonCommand(args, stderr=subprocess.STDOUT) # now test it try: - if isinstance(theOutputtext, bytes): - theOutputtext = theOutputtext.decode('utf8') + if isinstance(theOutputtxt, bytes): + theOutputtxt = theOutputtxt.decode('utf8') except UnicodeDecodeError: - theOutputtext = str(repr(bytes(theOutputtext))) + theOutputtxt = str(repr(bytes(theOutputtxt))) # or simply: - self.assertIsNotNone(theOutputtext) + self.assertIsNotNone(theOutputtxt) theResult = True except Exception as err: context.debugtestError(err) @@ -345,13 +346,13 @@ def test_profile_template_case(self): theResult = False assert theResult - # @unittest.expectedFailure + @unittest.expectedFailure def test_fail_message_works_case(self): """Test case template for profiling""" theResult = False if (self._thepython is not None): try: - for test_case in ["BAdInPut"]: + for test_case in ["BAdInPut", "1", "exit"]: args = [ str(self._thepython), str("-m"), @@ -362,16 +363,16 @@ def test_fail_message_works_case(self): ) ) ] - theOutputtext = context.checkPythonCommand(args, stderr=subprocess.STDOUT) + theOutputtxt = context.checkPythonCommand(args, stderr=subprocess.STDOUT) # now test it try: - if isinstance(theOutputtext, bytes): - theOutputtext = theOutputtext.decode('utf8') + if isinstance(theOutputtxt, bytes): + theOutputtxt = theOutputtxt.decode('utf8') except UnicodeDecodeError: - theOutputtext = str(repr(bytes(theOutputtext))) - theResult = debugIfNoneResult(self._thepython, args, theOutputtext) + theOutputtxt = str(repr(bytes(theOutputtxt))) + theResult = debugIfNoneResult(self._thepython, args, theOutputtxt) # or simply: - self.assertIsNotNone(theOutputtext) + self.assertIsNotNone(theOutputtxt) except Exception as err: context.debugtestError(err) err = None From 5c94cc7e2e291e1e368eca8be7e92f3611ab1add Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 21 Feb 2022 01:41:42 -0800 Subject: [PATCH 094/135] [REGRESION] fix for typo Acknowledgement --- multicast/recv.py | 2 +- multicast/send.py | 2 +- tests/profiling.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index c5b511ef..4c6005fd 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -18,7 +18,7 @@ # limitations under the License. -# Third-party Acknowlegement: +# Third-party Acknowledgement: # .......................................... # Some code (namely: run, and parseArgs) was modified/derived from: # https://stackoverflow.com/a/52791404 diff --git a/multicast/send.py b/multicast/send.py index 307af09b..a2a88cac 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -18,7 +18,7 @@ # limitations under the License. -# Third-party Acknowlegement: +# Third-party Acknowledgement: # .......................................... # Some code (namely: run, and parseArgs) was modified/derived from: # https://stackoverflow.com/a/52791404 diff --git a/tests/profiling.py b/tests/profiling.py index b3f93471..037198ef 100644 --- a/tests/profiling.py +++ b/tests/profiling.py @@ -18,7 +18,7 @@ # limitations under the License. -# Third-party Acknowlegement: +# Third-party Acknowledgement: # .......................................... # Some code (namely: class timewith, @do_cprofile, @do_line_profile) was modified/derived from: # https://github.com/zapier/profiling-python-like-a-boss/tree/1ab93a1154 From 4f08d114eb7c19e247852678b84e728ac9145402 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 21 Feb 2022 02:05:30 -0800 Subject: [PATCH 095/135] [STYLE] refactor prolog to prologue and epilog to match --- multicast/__init__.py | 6 +++--- multicast/__main__.py | 12 ++++++------ multicast/recv.py | 24 ++++++++++++------------ multicast/send.py | 4 ++-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/multicast/__init__.py b/multicast/__init__.py index c08e9655..576d5b75 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -17,7 +17,7 @@ # limitations under the License. __all__ = [ - """__package__""", """__module__""", """__name__""", """__version__""", """__prolog__""", + """__package__""", """__module__""", """__name__""", """__version__""", """__prologue__""", """__doc__""", """__MCAST_DEFAULT_PORT""", """recv""", """send""" ] @@ -37,10 +37,10 @@ __version__ = """1.3.0""" -__prolog__ = str("""Python Multicast library version {version}.""").format(version=__version__) +__prologue__ = str("""Python Multicast library version {version}.""").format(version=__version__) -__doc__ = __prolog__ + """ +__doc__ = __prologue__ + """ Minimal Acceptance Testing: diff --git a/multicast/__main__.py b/multicast/__main__.py index b1232c9f..9f53d3af 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -18,7 +18,7 @@ # limitations under the License. __all__ = [ - """__module__""", """__proc__""", """__prolog__""", """__epilog__""", + """__module__""", """__proc__""", """__prologue__""", """__epilogue__""", """__doc__""", """NoOp""", """SendMCast""", """joinMCast""", """dumpUsage""", """__checkToolArgs""", """buildArgs""", """TASK_OPTIONS""", """parseArgs""", """useTool""", """main""" @@ -40,13 +40,13 @@ __proc__ = """multicast""" -__prolog__ = """The Main Entrypoint""" +__prologue__ = """The Main Entrypoint""" -__epilog__ = """Add an epilog here.""" +__epilogue__ = """Add an epilogue here.""" -__doc__ = __prolog__ + """ +__doc__ = __prologue__ + """ Minimal Acceptance Testing: @@ -187,8 +187,8 @@ def buildArgs(): """ parser = argparse.ArgumentParser( prog=__proc__, - description=__prolog__, - epilog=__epilog__, + description=__prologue__, + epilog=__epilogue__, add_help=False ) group = parser.add_mutually_exclusive_group(required=False) diff --git a/multicast/recv.py b/multicast/recv.py index c5b511ef..eb79313e 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -32,8 +32,8 @@ __all__ = [ """genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", - """__module__""", """__name__""", """__proc__""", """__prolog__""", - """__epilog__""", """__doc__""" + """__module__""", """__name__""", """__proc__""", """__prologue__""", + """__epilogue__""", """__doc__""" ] @@ -52,13 +52,13 @@ __proc__ = """multicast HEAR""" -__epilog__ = """Generally speaking you want to bind to one of the groups you joined in +__epilogue__ = """Generally speaking you want to bind to one of the groups you joined in this module/instance, but it is also possible to bind to group which is added by some other programs (like another python program instance of this) """ -__prolog__ = """Python Multicast Receiver. Spawns a listener for multicast based on arguments.""" +__prologue__ = """Python Multicast Receiver. Spawns a listener for multicast based on arguments.""" try: @@ -239,8 +239,8 @@ def parseArgs(arguments=None): """ parser = argparse.ArgumentParser( prog=__proc__, - description=__prolog__, - epilog=__epilog__ + description=__prologue__, + epilog=__epilogue__ ) parser.add_argument('--port', type=int, default=__MCAST_DEFAULT_PORT) parser.add_argument( @@ -326,7 +326,7 @@ def main(*argv): return __exit_code -__doc__ = __prolog__ + """ +__doc__ = __prologue__ + """ Minimal Acceptance Testing: @@ -365,18 +365,18 @@ def main(*argv): True >>> type(multicast.recv.__doc__) == type(multicast.recv.__module__) True - >>> multicast.recv.__prolog__ is not None + >>> multicast.recv.__prologue__ is not None True - >>> type(multicast.recv.__doc__) == type(multicast.recv.__prolog__) + >>> type(multicast.recv.__doc__) == type(multicast.recv.__prologue__) True - >>> multicast.recv.__epilog__ is not None + >>> multicast.recv.__epilogue__ is not None True - >>> type(multicast.recv.__doc__) == type(multicast.recv.__epilog__) + >>> type(multicast.recv.__doc__) == type(multicast.recv.__epilogue__) True >>> type(multicast.recv.__doc__) == type(multicast.recv.__proc__) True >>> -""" + __epilog__ + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ +""" + __epilogue__ + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ diff --git a/multicast/send.py b/multicast/send.py index 307af09b..97f3cd2c 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -145,12 +145,12 @@ def parseArgs(*arguments): """ - __epilog__ = """- WIP -""" + __epilogue__ = """- WIP -""" __description__ = """Python Multicast Broadcaster.""" parser = argparse.ArgumentParser( prog=__proc__, description=__description__, - epilog=__epilog__ + epilog=__epilogue__ ) parser.add_argument("""--port""", type=int, default=__MCAST_DEFAULT_PORT) parser.add_argument('--mcast-group', default='224.1.1.1') From 0bc5c5ba9bafabb15ca3a436544ff58c9f05d220 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 22 Feb 2022 06:25:04 -0800 Subject: [PATCH 096/135] [STYLE] many minor refactors for converging the overall project style - WIP --- .coveragerc | 2 +- .gitattributes | 5 +- Makefile | 4 +- multicast/__init__.py | 84 +++++++++++++++++++- multicast/__main__.py | 28 +++++-- multicast/recv.py | 28 ++++--- multicast/send.py | 23 ++++-- setup.py | 51 +++++++++++- tests/{check_cc_line.bash => check_cc_lines} | 0 tests/test_usage.py | 5 +- 10 files changed, 187 insertions(+), 43 deletions(-) rename tests/{check_cc_line.bash => check_cc_lines} (100%) diff --git a/.coveragerc b/.coveragerc index 0b6dbb56..b4a35549 100644 --- a/.coveragerc +++ b/.coveragerc @@ -16,7 +16,6 @@ exclude_lines = raise AssertionError raise NotImplementedError raise ImportError - except unittest.SkipTest except subprocess.CalledProcessError except IOError except OSError @@ -33,6 +32,7 @@ exclude_lines = partial_branches = # Have to re-enable the standard pragma rules pragma: no branch + except unittest.SkipTest # Don't complain if non-runnable code isn't run: if __name__ in u'__main__': if __name__ in '__main__': diff --git a/.gitattributes b/.gitattributes index 9dd5936e..1640b879 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,12 +2,13 @@ *.cfg text diff=config *.txt text *.py text working-tree-encoding=UTF-8 diff=python -*.pyc -text multicast/*.py text working-tree-encoding=UTF-8 diff=python +tests/*.py text working-tree-encoding=UTF-8 diff=python +*.pyc -text *.sh text *.bash text diff=shell *.ini text -*.md text +*.md text working-tree-encoding=UTF-8 *.yml text *.jpg -text *.png -text diff --git a/Makefile b/Makefile index 80a386f5..0f06906f 100644 --- a/Makefile +++ b/Makefile @@ -127,10 +127,10 @@ test-pytest: cleanup test-reports $(QUIET)$(ECHO) "$@: Done." test-style: cleanup - $(QUIET)flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini + $(QUIET)flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || $(PYTHON) -m flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || true $(QUIET)tests/check_spelling 2>/dev/null || true + $(QUIET)tests/check_cc_lines 2>/dev/null || true $(QUIET)tests/check_codecov 2>/dev/null || true - $(QUIET)tests/check_cc_line.bash 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." cleanup: diff --git a/multicast/__init__.py b/multicast/__init__.py index 576d5b75..01e19568 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -16,28 +16,34 @@ # See the License for the specific language governing permissions and # limitations under the License. +"""Contains the Python Multicast library.""" + __all__ = [ """__package__""", """__module__""", """__name__""", """__version__""", """__prologue__""", - """__doc__""", """__MCAST_DEFAULT_PORT""", """recv""", """send""" + """__doc__""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", + """__MCAST_DEFAULT_TTL""", """recv""", """send""" ] __package__ = """multicast""" +"""The package of this program.""" __module__ = """multicast""" +"""The module of this program.""" __name__ = """multicast""" +"""The name of this program.""" global __version__ -"""The version of this program.""" - __version__ = """1.3.0""" +"""The version of this program.""" __prologue__ = str("""Python Multicast library version {version}.""").format(version=__version__) +"""The one-line description or summary of this program.""" __doc__ = __prologue__ + """ @@ -66,10 +72,32 @@ True >>> + Testcase 1: multicast.send should have a doctests. + + >>> import multicast.send + >>> + + >>> multicast.send.__module__ is not None + True + >>> + + Testcase 2: multicast.__main__ should have a doctests. + + >>> import multicast.__main__ as _main + >>> + + >>> _main.__module__ is not None + True + >>> _main.__doc__ is not None + True + >>> + """ global __MCAST_DEFAULT_PORT + +__MCAST_DEFAULT_PORT = 19991 """ Arbitrary port to use by default, though any dynamic and free port would work. @@ -92,7 +120,55 @@ """ -__MCAST_DEFAULT_PORT = 19991 +global __MCAST_DEFAULT_GROUP + +__MCAST_DEFAULT_GROUP = """224.0.0.1""" +""" + Arbitrary group to use by default, though any mcst grp would work. + + Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> + + Testcase 0: Multicast should have a default port. + A: Test that the __MCAST_DEFAULT_GROUP attribute is initialized. + B: Test that the __MCAST_DEFAULT_GROUP attribute is an IP string. + + >>> multicast.__MCAST_DEFAULT_GROUP is not None + True + >>> type(multicast.__MCAST_DEFAULT_GROUP) is type(str) + True + >>> + +""" + +global __MCAST_DEFAULT_TTL + +__MCAST_DEFAULT_TTL = 20 +""" + Arbitrary TTL time to live to use by default, though any small (2-126) TTL would work. + + Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> + + Testcase 0: Multicast should have a default TTL. + A: Test that the __MCAST_DEFAULT_TTL attribute is initialized. + B: Test that the __MCAST_DEFAULT_TTL attribute is an int. + + >>> multicast.__MCAST_DEFAULT_TTL is not None + True + >>> type(multicast.__MCAST_DEFAULT_TTL) is type(1) + True + >>> + +""" try: diff --git a/multicast/__main__.py b/multicast/__main__.py index 9f53d3af..b81644e5 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -17,18 +17,22 @@ # See the License for the specific language governing permissions and # limitations under the License. +"""The Main Entrypoint.""" + + __all__ = [ - """__module__""", """__proc__""", """__prologue__""", """__epilogue__""", - """__doc__""", """NoOp""", """SendMCast""", """joinMCast""", + """__package__""", """__module__""", """__name__""", """__proc__""", + """NoOp""", """SendMCast""", """joinMCast""", """dumpUsage""", """__checkToolArgs""", """buildArgs""", - """TASK_OPTIONS""", """parseArgs""", """useTool""", """main""" + """__prologue__""", """__epilogue__""", + """__doc__""", """main""" ] __package__ = """multicast""" -__module__ = """multicast.__main__""" +__module__ = """multicast""" __file__ = """multicast/__main__.py""" @@ -40,7 +44,7 @@ __proc__ = """multicast""" -__prologue__ = """The Main Entrypoint""" +__prologue__ = """The Main Entrypoint.""" __epilogue__ = """Add an epilogue here.""" @@ -52,13 +56,19 @@ First setup test fixtures by importing multicast. - >>> import multicast + >>> import multicast as multicast + >>> + >>> import multicast.__main__ >>> >>> multicast.__doc__ is not None True >>> + >>> multicast.__main__.__doc__ is not None + True + >>> + >>> multicast.__version__ is not None True >>> @@ -123,14 +133,16 @@ def NoOp(*args, **kwargs): - """The meaning of Nothing. This function should be self-explanitory; + """The meaning of Nothing. + + This function should be self-explanitory; it does 'no operation' i.e. nothing. Minimal Acceptance Testing: First setup test fixtures by importing multicast. - >>> import multicast + >>> import multicast.__main__ >>> Testcase 0: multicast.__main__ should have a doctests. diff --git a/multicast/recv.py b/multicast/recv.py index 35a21522..2c304532 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -30,6 +30,8 @@ # .......................................... # NO ASSOCIATION +"""multicast HEAR ...""" + __all__ = [ """genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", """__module__""", """__name__""", """__proc__""", """__prologue__""", @@ -93,7 +95,7 @@ def genSocket(): - """Generates an unbound socket.socket object ready to receive network traffic. + """Will generate an unbound socket.socket object ready to receive network traffic. Minimal Acceptance Testing: @@ -139,7 +141,7 @@ def genSocket(): def endSocket(sock=None): - """Generates an unbound socket.socket object ready to receive network traffic. + """Will generates an unbound socket.socket object ready to receive network traffic. Minimal Acceptance Testing: @@ -195,17 +197,18 @@ def endSocket(sock=None): """ - if not (sock is None): + if not (sock is None): # pragma: no branch try: sock.shutdown(socket.SHUT_RD) sock.close() except OSError: sock = None - return None def parseArgs(arguments=None): - """Parses the CLI arguments. See argparse.ArgumentParser for more. + """Will attempt to parse the given CLI arguments. + + See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs. @@ -267,7 +270,8 @@ def parseArgs(arguments=None): def hearstep(groups, port, iface=None, bind_group=None): - """ + """Will listen on the given port of an interface for multicast messages to the given group(s). + The work-horse function. """ if groups is None: @@ -291,20 +295,20 @@ def hearstep(groups, port, iface=None, bind_group=None): chunk = None # msgbuffer += unicodedata.lookup("""SOFT HYPHEN""") # about 969 bytes in base64 encoded as chars - except KeyboardInterrupt: + except KeyboardInterrupt: # pragma: no branch print("""""") print(str("""User Interrupted""")) - except OSError: + except OSError: # pragma: no branch print(str("""""")) finally: sock = endSocket(sock) - # print(str("""""")) - # print(str(msgbuffer)) return msgbuffer def main(*argv): - """The Main Event. This does two things: + """Will handle the Main Event from multicast.__main__ when called. + + This does two things: 1: calls parseArgs() and passes the given arguments, handling any errors if needed. 2: calls hearstep with the parsed args if able and handles any errors regardles @@ -323,7 +327,7 @@ def main(*argv): except Exception as e: print(str(e)) __exit_code = 3 - return __exit_code + return int(__exit_code) __doc__ = __prologue__ + """ diff --git a/multicast/send.py b/multicast/send.py index 1fe778af..8ca4717e 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -30,6 +30,8 @@ # .......................................... # NO ASSOCIATION +"""multicast SAY ...""" + __all__ = [ """main""", """saystep""", """parseArgs""", """__module__""", """__name__""", """__doc__""" @@ -113,7 +115,9 @@ def parseArgs(*arguments): - """Parses the CLI arguments. See argparse.ArgumentParser for more. + """Will attempt to parse the given CLI arguments. + + See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs. @@ -143,7 +147,6 @@ def parseArgs(*arguments): <...Namespace...> >>> - """ __epilogue__ = """- WIP -""" __description__ = """Python Multicast Broadcaster.""" @@ -162,7 +165,10 @@ def parseArgs(*arguments): def saystep(group, port, data): - """The actual magic is handeled here.""" + """Will send the given data over the given port to the given group. + + The actual magic is handeled here. + """ MULTICAST_TTL = 20 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) try: @@ -171,23 +177,24 @@ def saystep(group, port, data): finally: try: sock.close() - except OSError: + except OSError: # pragma: no branch False sock = None def main(*argv): - """The Main Event.""" + """Will handle the Main Event from multicast.__main__ when called.""" __exit_code = 1 try: args = parseArgs(*argv) saystep(args.mcast_group, int(args.port), args.message) __exit_code = 0 - except argparse.ArgumentError: + except argparse.ArgumentError: # pragma: no branch print('Input has an Argument Error') __exit_code = 2 - except Exception as e: + except Exception as e: # pragma: no branch print(str(e)) __exit_code = 3 - return __exit_code + del e + return int(__exit_code) diff --git a/setup.py b/setup.py index 1d6ea7d7..c0c6c158 100755 --- a/setup.py +++ b/setup.py @@ -17,6 +17,25 @@ # See the License for the specific language governing permissions and # limitations under the License. +"""Sets up the package.""" + +__prologue__ = """Python Multicast Repo for Send/Recv Stubs.""" +"""The one-line description or summary of this program.""" + +__doc__ = __prologue__ + """ + +Minimal Acceptance Testing: + + Just setup test fixtures by importing multicast. + + >>> import multicast + >>> + >>> multicast.__package__ is not None + True + >>> + +""" + try: from setuptools import setup from setuptools import find_packages @@ -25,7 +44,26 @@ def readFile(filename): - """Helper Function to read files""" + """Will attempt to read the file at with the given filename or path. + + Used as a helper function to read files and return strings with the content. + + Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> + + Testcase 0: Should have Function readFile() WHEN loading setup.py. + + >>> multicast.readFile is not None + True + >>> type(multicast.readFile) is type(1) + False + >>> + + """ theResult = None try: with open(str("""./{}""").format(str(filename))) as f: @@ -34,7 +72,7 @@ def readFile(filename): theResult = str( """See https://github.com/reactive-firewall/multicast/{}""" ).format(filename) - return theResult + return str(theResult) try: @@ -44,11 +82,17 @@ def readFile(filename): requirements = None readme = readFile("""README.md""") +"""The multi-line description and/or summary of this program.""" + SLA = readFile("""LICENSE.md""") +"""The "Software License Agreement" of this program.""" try: class_tags = [ str("""Development Status :: 4 - Beta"""), + str("""Environment :: Console"""), + str("""Intended Audience :: Developers"""), + str("""Operating System :: MacOS :: MacOS X"""), str("""Operating System :: POSIX :: Linux"""), str("""License :: OSI Approved :: MIT License"""), str("""Programming Language :: Python"""), @@ -60,11 +104,10 @@ def readFile(filename): except Exception: class_tags = str("""Development Status :: 4 - Beta""") - setup( name="""multicast""", version="""1.3.0""", - description="""Python Multicast Repo for Send/Recv Stubs""", + description=__prologue__, long_description=readme, long_description_content_type="""text/markdown""", zip_safe=False, diff --git a/tests/check_cc_line.bash b/tests/check_cc_lines similarity index 100% rename from tests/check_cc_line.bash rename to tests/check_cc_lines diff --git a/tests/test_usage.py b/tests/test_usage.py index 5f090a87..81ae09ec 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -346,8 +346,7 @@ def test_profile_template_case(self): theResult = False assert theResult - @unittest.expectedFailure - def test_fail_message_works_case(self): + def test_invalid_Error_WHEN_cli_called_GIVEN_bad_input(self): """Test case template for profiling""" theResult = False if (self._thepython is not None): @@ -373,6 +372,8 @@ def test_fail_message_works_case(self): theResult = debugIfNoneResult(self._thepython, args, theOutputtxt) # or simply: self.assertIsNotNone(theOutputtxt) + self.assertIn(str("invalid choice:"), str(theOutputtxt)) + self.assertIn(str(test_case), str(theOutputtxt)) except Exception as err: context.debugtestError(err) err = None From a2f82328975f63fdc7c55214d471a5ebc8acfe86 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 23 Feb 2022 04:18:57 -0800 Subject: [PATCH 097/135] [STYLE] Churn churn but more stable --- Makefile | 17 ++--- multicast/__init__.py | 84 ++++++++++++++++++---- multicast/__main__.py | 132 ++++++++++++++++++++++++++--------- multicast/recv.py | 92 +++++++++++++++++++++++-- multicast/send.py | 157 ++++++++++++++++++++++++++++++++++-------- setup.py | 2 +- tests/__init__.py | 11 ++- tests/context.py | 27 ++++---- tests/test_basic.py | 6 +- tests/test_usage.py | 3 +- 10 files changed, 418 insertions(+), 113 deletions(-) diff --git a/Makefile b/Makefile index 0f06906f..d7ba2797 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ ifeq "$(LINK)" "" endif ifeq "$(MAKE)" "" - MAKE=make + MAKE=make -j1 endif ifeq "$(PYTHON)" "" @@ -37,12 +37,7 @@ ifeq "$(PYTHON)" "" endif ifeq "$(COVERAGE)" "" - ifeq "$(COVERAGE)" "" - COVERAGE=`command -v coverage` - endif - ifeq "$(COVERAGE)" "" - COVERAGE=`command -v coverage3` - endif + COVERAGE=$(PYTHON) -m coverage endif ifeq "$(WAIT)" "" @@ -108,7 +103,7 @@ purge: clean uninstall $(QUIET)$(ECHO) "$@: Done." test: cleanup - $(QUIET)$(COVERAGE) run -p --source=multicast* -m unittest discover --buffer --verbose -s ./tests -t ./ tests 2>/dev/null || $(PYTHON) -m unittest discover --verbose --buffer -s ./tests -t ./ tests || DO_FAIL="exit 2" ; + $(QUIET)$(COVERAGE) run -p --source=multicast -m unittest discover --verbose --buffer -s ./tests -t ./ || $(PYTHON) -m unittest discover --verbose --buffer -s ./tests -t ./ || DO_FAIL="exit 2" ; $(QUIET)$(COVERAGE) combine 2>/dev/null || true ; $(QUIET)$(COVERAGE) report --include=multicast* 2>/dev/null || true ; $(QUIET)$(DO_FAIL) ; @@ -123,7 +118,7 @@ test-reports: $(QUIET)$(ECHO) "$@: Done." test-pytest: cleanup test-reports - $(QUIET)$(PYTHON) -m pytest --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests || python -m pytest --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v tests ; wait ; + $(QUIET)$(PYTHON) -m pytest --cache-clear --doctest-glob=**/*.py --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v --rootdir=. || python -m pytest --doctest-glob=**/*.py --doctest-modules --cov=./ --cov-report=xml --junitxml=test-reports/junit.xml -v . ; wait ; $(QUIET)$(ECHO) "$@: Done." test-style: cleanup @@ -134,10 +129,10 @@ test-style: cleanup $(QUIET)$(ECHO) "$@: Done." cleanup: - $(QUIET)$(COVERAGE) erase 2>/dev/null || true $(QUIET)$(RM) tests/*.pyc 2>/dev/null || true $(QUIET)$(RM) tests/*~ 2>/dev/null || true $(QUIET)$(RM) tests/__pycache__/* 2>/dev/null || true + $(QUIET)$(RM) __pycache__/* 2>/dev/null || true $(QUIET)$(RM) multicast/*.pyc 2>/dev/null || true $(QUIET)$(RM) multicast/*~ 2>/dev/null || true $(QUIET)$(RM) multicast/__pycache__/* 2>/dev/null || true @@ -163,6 +158,7 @@ cleanup: $(QUIET)$(RMDIR) tests/__pycache__ 2>/dev/null || true $(QUIET)$(RMDIR) multicast/__pycache__ 2>/dev/null || true $(QUIET)$(RMDIR) multicast/*/__pycache__ 2>/dev/null || true + $(QUIET)$(RMDIR) ./__pycache__ 2>/dev/null || true $(QUIET)$(RMDIR) multicast.egg-info 2>/dev/null || true $(QUIET)$(RMDIR) .pytest_cache/ 2>/dev/null || true $(QUIET)$(RMDIR) .eggs 2>/dev/null || true @@ -171,6 +167,7 @@ cleanup: $(QUIET)$(WAIT) ; clean: cleanup + $(QUIET)$(COVERAGE) erase 2>/dev/null || true $(QUIET)$(RM) ./test-results/junit.xml 2>/dev/null || true $(QUIET)$(RMDIR) ./test-results/ 2>/dev/null || true $(QUIET)$(RMDIR) ./build/ 2>/dev/null || true diff --git a/multicast/__init__.py b/multicast/__init__.py index 01e19568..93237cf2 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -20,26 +20,78 @@ __all__ = [ """__package__""", """__module__""", """__name__""", """__version__""", """__prologue__""", - """__doc__""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", - """__MCAST_DEFAULT_TTL""", """recv""", """send""" + """__builtins__""", """__doc__""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", + """__MCAST_DEFAULT_TTL""", """recv""", """send""", """__main__""" ] __package__ = """multicast""" -"""The package of this program.""" +"""The package of this program. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast as _multicast + >>> + + >>> _multicast.__package__ is not None + True + >>> + +""" __module__ = """multicast""" -"""The module of this program.""" +"""The module of this program. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast as _multicast + >>> + + >>> _multicast.__module__ is not None + True + >>> + +""" __name__ = """multicast""" -"""The name of this program.""" +"""The name of this program. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast as _multicast + >>> + + >>> _multicast.__name__ is not None + True + >>> + +""" global __version__ __version__ = """1.3.0""" -"""The version of this program.""" +"""The version of this program. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast as _multicast + >>> + + >>> _multicast.__version__ is not None + True + >>> + +""" __prologue__ = str("""Python Multicast library version {version}.""").format(version=__version__) @@ -83,6 +135,7 @@ Testcase 2: multicast.__main__ should have a doctests. + >>> import multicast as _multicast >>> import multicast.__main__ as _main >>> @@ -92,7 +145,8 @@ True >>> - """ + +""" global __MCAST_DEFAULT_PORT @@ -231,14 +285,16 @@ import multicast.send as send -if __name__ in '__main__': - try: - if 'multicast.__main__' not in sys.modules: - from . import __main__ as __main__ - else: # pragma: no branch - __main__ = sys.modules["""multicast.__main__"""] - except Exception: +try: + if 'multicast.__main__' not in sys.modules: from . import __main__ as __main__ + else: # pragma: no branch + __main__ = sys.modules["""multicast.__main__"""] +except Exception: + from . import __main__ as __main__ + + +if __name__ in '__main__': __EXIT_CODE = 2 if __main__.__name__ is None: raise ImportError(str("Failed to open multicast")) diff --git a/multicast/__main__.py b/multicast/__main__.py index b81644e5..d9e97cf5 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -22,10 +22,9 @@ __all__ = [ """__package__""", """__module__""", """__name__""", """__proc__""", - """NoOp""", """SendMCast""", """joinMCast""", - """dumpUsage""", """__checkToolArgs""", """buildArgs""", - """__prologue__""", """__epilogue__""", - """__doc__""", """main""" + """__prologue__""", """__epilogue__""", """__doc__""", """__checkToolArgs""", + """NoOp""", """SendMCast""", """joinMCast""", """dumpUsage""", + """buildArgs""", """main""" ] @@ -82,6 +81,10 @@ True >>> + >>> multicast.__main__.__doc__ is not None + True + >>> + """ @@ -99,7 +102,7 @@ err = None del(err) # Throw more relevant Error - raise ImportError(str("Error Importing Python")) + raise ImportError(str("[CWE-440] Error Importing Python")) try: @@ -133,9 +136,9 @@ def NoOp(*args, **kwargs): - """The meaning of Nothing. + """Do Nothing. - This function should be self-explanitory; + The meaning of Nothing. This function should be self-explanitory; it does 'no operation' i.e. nothing. Minimal Acceptance Testing: @@ -162,23 +165,23 @@ def NoOp(*args, **kwargs): >>> """ - return None + return None # noqa def SendMCast(*args, **kwargs): - """Sends a multicast message""" + """Will Send a multicast message.""" return send.main(*args, **kwargs) def joinMCast(*args, **kwargs): - """recv multicast messages""" + """Will listen for multicast messages.""" return recv.main(*args, **kwargs) def dumpUsage(*args, **kwargs): - """Prints help usage""" + """Will prints help usage.""" buildArgs().print_help() - return None + return None # noqa # More boiler-plate-code @@ -194,8 +197,34 @@ def dumpUsage(*args, **kwargs): def buildArgs(): - """Utility Function to build argparse parser. + """Will build the argparse parser. + + Utility Function to build the argparse parser; see argparse.ArgumentParser for more. returns argparse.ArgumentParser - the ArgumentParser to use. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> import multicast.__main__ + >>> multicast.__main__ is not None + True + >>> + + Testcase 0: buildArgs should return an ArgumentParser. + A: Test that the multicast.__main__ component is initialized. + B: Test that the recv.buildArgs component is initialized. + + >>> multicast.__main__ is not None + True + >>> multicast.__main__.buildArgs is not None + True + >>> type(multicast.__main__.buildArgs()) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + <...ArgumentParser...> + >>> + + """ parser = argparse.ArgumentParser( prog=__proc__, @@ -219,16 +248,49 @@ def buildArgs(): def parseArgs(arguments=None): - """Parses the CLI arguments. See argparse.ArgumentParser for more. + """Will attempt to parse the given CLI arguments. + + See argparse.ArgumentParser for more. param str - arguments - the array of arguments to parse. Usually sys.argv[1:] returns argparse.Namespace - the Namespace parsed with the key-value pairs. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> import multicast.__main__ + >>> multicast.__main__ is not None + True + >>> + + Testcase 0: parseArgs should return a namespace. + A: Test that the multicast.__main__ component is initialized. + B: Test that the __main__ component is initialized. + C: Test that the __main__.parseArgs component is initialized. + + >>> multicast.__main__ is not None + True + >>> multicast.__main__.parseArgs is not None + True + >>> tst_fxtr_args = ['''NOOP''', '''--port=1234''', '''--iface=127.0.0.1'''] + >>> test_fixture = multicast.__main__.parseArgs(tst_fxtr_args) + >>> test_fixture is not None + True + >>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + <...Namespace...> + >>> + + """ arguments = __checkToolArgs(arguments) return buildArgs().parse_known_intermixed_args(arguments) def __checkToolArgs(args): - """Handles None case for arguments as a helper function. + """Will handle the None case for arguments. + + Used as a helper function. Minimal Acceptance Testing: @@ -258,56 +320,58 @@ def __checkToolArgs(args): >>> import multicast.__main__ >>> type(multicast.__main__.__checkToolArgs(["arg1", "arg2"])) is type(["strings"]) True + >>> type(multicast.__main__.__checkToolArgs([0, 42])) is type([int(1)]) + True >>> """ - if args is None: - args = [None] - return args + return [None] if args is None else args def useTool(tool, *arguments): - """Handler for launching the functions.""" + """Will Handle launching the actual task functions.""" theResult = None arguments = __checkToolArgs(arguments) if (tool is not None) and (tool in TASK_OPTIONS.keys()): try: - # print(str("launching: " + tool)) theResult = TASK_OPTIONS[tool](*arguments) - except Exception: - raise NotImplementedError("""Not Implemented.""") - return theResult + except Exception: # pragma: no branch + raise NotImplementedError("""[CWE-440] Not Implemented.""") + return theResult # noqa def main(*argv): - """The Main Event.""" + """Do main event stuff.""" __EXIT_CODE = 1 try: try: - args, extra = parseArgs(*argv) + (args, extra) = parseArgs(*argv) service_cmd = args.some_task __EXIT_CODE = useTool(service_cmd, extra) - except Exception as inerr: + except Exception as inerr: # pragma: no branch w = str("WARNING - An error occured while") w += str(" handling the arguments.") w += str(" Cascading failure.") - print(w) - print(str(inerr)) - print(str(inerr.args())) + if (sys.stdout.isatty()): # pragma: no cover + print(w) + print(str(inerr)) + print(str(inerr.args())) + del inerr __EXIT_CODE = 2 - except Exception: + except BaseException: # pragma: no branch e = str("CRITICAL - An error occured while handling") e += str(" the cascading failure.") - print(e) + if (sys.stdout.isatty()): # pragma: no cover + print(str(e)) __EXIT_CODE = 3 - return __EXIT_CODE + return __EXIT_CODE # noqa -if __name__ in u'__main__': +if __name__ in '__main__': __EXIT_CODE = 2 if (sys.argv is not None) and (len(sys.argv) > 1): __EXIT_CODE = main(sys.argv[1:]) - else: + elif (sys.argv is not None): __EXIT_CODE = main([str(__proc__), """-h"""]) exit(__EXIT_CODE) diff --git a/multicast/recv.py b/multicast/recv.py index 2c304532..2a6f7078 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -33,7 +33,7 @@ """multicast HEAR ...""" __all__ = [ - """genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", + """__package__""", """genSocket""", """endSocket""", """parseArgs""", """hearstep""", """main""", """__module__""", """__name__""", """__proc__""", """__prologue__""", """__epilogue__""", """__doc__""" ] @@ -89,7 +89,7 @@ from . import __MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT else: # pragma: no branch __MCAST_DEFAULT_PORT = sys.modules["""multicast.__MCAST_DEFAULT_PORT"""] -except Exception as importErr: +except Exception as importErr: # pragma: no branch del importErr import multicast.__MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT @@ -162,7 +162,7 @@ def endSocket(sock=None): True >>> - Testcase 1: Recv should have endSocket() function that takes a socket.socket object and closes it. + Testcase 1: Recv should have endSocket() function that takes a socket.socket and closes it. A: Test that the recv component has the function 'genSocket' B: Test that the recv component has the function 'endSocket' C: Test that the 'endSocket' function returns None when given the genSocket @@ -199,8 +199,8 @@ def endSocket(sock=None): """ if not (sock is None): # pragma: no branch try: - sock.shutdown(socket.SHUT_RD) sock.close() + sock.shutdown(socket.SHUT_RD) except OSError: sock = None @@ -273,6 +273,40 @@ def hearstep(groups, port, iface=None, bind_group=None): """Will listen on the given port of an interface for multicast messages to the given group(s). The work-horse function. + + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.recv is not None + True + >>> + + Testcase 1: Stability testing. + + >>> import multicast + >>> + >>> multicast.recv is None + False + >>> + >>> multicast.recv.hearstep is None + False + >>> type(multicast.recv.hearstep) + + >>> multicast.recv.hearstep(None, 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + '...' + >>> multicast.recv.hearstep([multicast.__MCAST_DEFAULT_GROUP], 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + '...' + >>> multicast.recv.hearstep([multicast.__MCAST_DEFAULT_GROUP], 19991, None, multicast.__MCAST_DEFAULT_GROUP) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + '...' + >>> + + """ if groups is None: groups = [] @@ -313,14 +347,58 @@ def main(*argv): 1: calls parseArgs() and passes the given arguments, handling any errors if needed. 2: calls hearstep with the parsed args if able and handles any errors regardles + Every main(*args) function in multicast is expected to return an int(). Regardles of errors the result as an 'exit code' (int) is returned. - (Note the __main__ handler just exits with this code as a true return code status.) + The only exception is multicast.__main__.main(*args) which will exit with the underlying + return codes. + The expected return codes are as follows: + = 0: Any nominal state (i.e. no errors and possibly success) + <=1: Any erroneous state (caveat: includes simple failure) + = 2: Any failed state + = 3: Any undefined (but assumed erroneous) state + > 0: implicitly erroneous and treated same as abs(exit_code) would be. + + param iterable - argv - the array of arguments. Usually sys.argv[1:] + returns int - the Namespace parsed with the key-value pairs. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.send is not None + True + >>> + + Testcase 0: main should return an int. + A: Test that the multicast component is initialized. + B: Test that the send component is initialized. + C: Test that the send.main function is initialized. + D: Test that the send.main function returns an int 0-3. + + >>> multicast.send is not None + True + >>> multicast.send.main is not None + True + >>> tst_fxtr_args = ['''--port=1234''', '''--message''', '''is required'''] + >>> test_fixture = multicast.send.main(tst_fxtr_args) + >>> test_fixture is not None + True + >>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + <...int...> + >>> int(test_fixture) >= int(0) + True + >>> int(test_fixture) < int(4) + True + >>> + """ - __exit_code = 0 + __exit_code = 1 try: args = parseArgs(*argv) hearstep(args.join_mcast_groups, int(args.port), args.iface, args.bind_group) + __exit_code = 0 except argparse.ArgumentError: print('Input has an Argument Error') __exit_code = 2 @@ -367,6 +445,8 @@ def main(*argv): True >>> multicast.recv.__module__ is not None True + >>> multicast.recv.__package__ is not None + True >>> type(multicast.recv.__doc__) == type(multicast.recv.__module__) True >>> multicast.recv.__prologue__ is not None diff --git a/multicast/send.py b/multicast/send.py index 8ca4717e..1eff8e62 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -30,30 +30,43 @@ # .......................................... # NO ASSOCIATION -"""multicast SAY ...""" +"""Python Multicast Broadcaster. -__all__ = [ - """main""", """saystep""", """parseArgs""", - """__module__""", """__name__""", """__doc__""" -] +Minimal Acceptance Testing: + First setup test fixtures by importing multicast. -__package__ = """multicast""" + Testcase 0: Multicast should be importable. + >>> import multicast + >>> -__module__ = """multicast""" + Testcase 1: Send should be automaticly imported. + A: Test that the send component is initialized. + B: Test that the send.__MAGIC__ components are initialized. + >>> multicast.send is not None + True + >>> -__file__ = """multicast/send.py""" + >>> multicast.send.__doc__ is not None + True + >>> + >>> multicast.send.__module__ is not None + True + >>> -__name__ = """multicast.send""" + >>> multicast.send.__proc__ is not None + True + >>> -__proc__ = "multicast SAY" +""" -__doc__ = """Python Multicast Broadcaster. +__package__ = """multicast""" +"""The package of this program. Minimal Acceptance Testing: @@ -64,27 +77,65 @@ >>> import multicast >>> - >>> multicast.__doc__ is not None + Testcase 1: Send should be automaticly imported. + + >>> multicast.send.__package__ is not None True >>> - Testcase 1: Recv should be automaticly imported. - A: Test that the __main__ component is initialized. - B: Test that the send component is initialized. +""" + + +__module__ = """multicast""" +"""The module of this program. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + Testcase 0: Multicast should be importable. >>> import multicast - >>> import multicast.__main__ >>> - >>> multicast.__main__ is not None - True - >>> multicast.send is not None + + Testcase 1: Send should be automaticly imported. + + >>> multicast.send.__module__ is not None True >>> +""" + + +__file__ = """multicast/send.py""" +"""The file of this component.""" + + +__name__ = """multicast.send""" +"""The name of this component. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + Testcase 0: Multicast should be importable. + + >>> import multicast + >>> + + Testcase 1: Send should be automaticly imported. + + >>> multicast.send.__name__ is not None + True + >>> """ +__proc__ = """multicast SAY""" +"""The name of this program.""" + + try: import sys import socket @@ -105,13 +156,13 @@ try: - if 'multicast.__MCAST_DEFAULT_PORT' not in sys.modules: - from . import __MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT + if 'multicast' not in sys.modules: + from . import multicast as multicast else: # pragma: no branch - __MCAST_DEFAULT_PORT = sys.modules["""multicast.__MCAST_DEFAULT_PORT"""] + multicast = sys.modules["""multicast"""] except Exception as importErr: del importErr - import multicast.__MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT + import multicast as multicast def parseArgs(*arguments): @@ -139,7 +190,7 @@ def parseArgs(*arguments): True >>> multicast.send.parseArgs is not None True - >>> tst_fxtr_args = ['''--port=1234''', '''--mesage''', '''is required'''] + >>> tst_fxtr_args = ['''--port=1234''', '''--message''', '''is required'''] >>> test_fixture = multicast.send.parseArgs(tst_fxtr_args) >>> test_fixture is not None True @@ -147,6 +198,7 @@ def parseArgs(*arguments): <...Namespace...> >>> + """ __epilogue__ = """- WIP -""" __description__ = """Python Multicast Broadcaster.""" @@ -155,8 +207,8 @@ def parseArgs(*arguments): description=__description__, epilog=__epilogue__ ) - parser.add_argument("""--port""", type=int, default=__MCAST_DEFAULT_PORT) - parser.add_argument('--mcast-group', default='224.1.1.1') + parser.add_argument("""--port""", type=int, default=multicast.__MCAST_DEFAULT_PORT) + parser.add_argument("""--mcast-group""", default=multicast.__MCAST_DEFAULT_GROUP) parser.add_argument( """--message""", dest="""message""", default=str("""PING from multicast_send.py: group: {group}, port: {port}""") @@ -169,10 +221,9 @@ def saystep(group, port, data): The actual magic is handeled here. """ - MULTICAST_TTL = 20 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) try: - sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL) + sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, multicast.__MCAST_DEFAULT_TTL) sock.sendto(data.encode('utf8'), (group, port)) finally: try: @@ -183,7 +234,55 @@ def saystep(group, port, data): def main(*argv): - """Will handle the Main Event from multicast.__main__ when called.""" + """Will handle the Main Event from multicast.__main__ when called. + + Every main(*args) function in multicast is expected to return an int(). + Regardles of errors the result as an 'exit code' (int) is returned. + The only exception is multicast.__main__.main(*args) which will exit with the underlying + return codes. + The expected return codes are as follows: + = 0: Any nominal state (i.e. no errors and possibly success) + <=1: Any erroneous state (caveat: includes simple failure) + = 2: Any failed state + = 3: Any undefined (but assumed erroneous) state + > 0: implicitly erroneous and treated same as abs(exit_code) would be. + + param iterable - argv - the array of arguments. Usually sys.argv[1:] + returns int - the Namespace parsed with the key-value pairs. + + Minimal Acceptance Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> multicast.send is not None + True + >>> + + Testcase 0: main should return an int. + A: Test that the multicast component is initialized. + B: Test that the send component is initialized. + C: Test that the send.main function is initialized. + D: Test that the send.main function returns an int 0-3. + + >>> multicast.send is not None + True + >>> multicast.send.main is not None + True + >>> tst_fxtr_args = ['''--port=1234''', '''--message''', '''is required'''] + >>> test_fixture = multicast.send.main(tst_fxtr_args) + >>> test_fixture is not None + True + >>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + <...int...> + >>> int(test_fixture) >= int(0) + True + >>> int(test_fixture) < int(4) + True + >>> + + + """ __exit_code = 1 try: args = parseArgs(*argv) diff --git a/setup.py b/setup.py index c0c6c158..4c3a0d64 100755 --- a/setup.py +++ b/setup.py @@ -40,7 +40,7 @@ from setuptools import setup from setuptools import find_packages except Exception: - raise ImportError("""Not Implemented.""") + raise NotImplementedError("""[CWE-440] Not Implemented.""") def readFile(filename): diff --git a/tests/__init__.py b/tests/__init__.py index e4f3bdba..7cc9de47 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -135,8 +135,7 @@ def load_tests(loader, tests, pattern): - """ - Loads the tests from the project and then attempts to load the doctests too. + """Loads the tests from the project and then attempts to load the doctests too. Testing: @@ -152,7 +151,13 @@ def load_tests(loader, tests, pattern): True """ - import doctest + try: + if 'doctest' not in sys.modules: + import doctest + else: # pragma: no branch + doctest = sys.modules["""doctest"""] + except Exception: # pragma: no branch + raise ImportError("[CWE-440] doctest Failed to import.") finder = doctest.DocTestFinder(verbose=True, recurse=True, exclude_empty=True) suite = unittest.TestSuite() for test_class in test_cases: diff --git a/tests/context.py b/tests/context.py index 3826e347..e8f37854 100644 --- a/tests/context.py +++ b/tests/context.py @@ -264,7 +264,7 @@ def checkStrOrByte(theInput): try: theOutput = theInput if isinstance(theInput, bytes): - theOutput = theInput.decode("""utf_8""") + theOutput = theInput.decode("""UTF-8""") except UnicodeDecodeError: theOutput = bytes(theInput) return theOutput @@ -316,17 +316,17 @@ def checkPythonFuzzing(args=[None], stderr=None): def debugBlob(blob=None): try: - print(str("")) + print(__BLANK) print(str("String:")) print(str("""\"""")) print(str(blob)) print(str("""\"""")) - print(str("")) + print(__BLANK) print(str("Data:")) print(str("""\"""")) print(repr(blob)) print(str("""\"""")) - print(str("")) + print(__BLANK) except Exception: return False return True @@ -370,7 +370,7 @@ def debugtestError(someError): >>> """ - print(str("")) + print(__BLANK) print(str("ERROR:")) if someError is not None: print(str(type(someError))) @@ -379,7 +379,7 @@ def debugtestError(someError): print(str((someError.args))) else: print(str("")) - print(str("")) + print(__BLANK) def check_exec_command_has_output(test_case, someArgs): @@ -459,21 +459,21 @@ def debugUnexpectedOutput(expectedOutput, actualOutput, thepython): >>> """ - print(str("")) + print(__BLANK) if (thepython is not None): print(str("python cmd used: {}").format(str(thepython))) else: print("Warning: Unexpected output!") - print(str("")) + print(__BLANK) if (expectedOutput is not None): print(str("The expected output is...")) - print(str("")) + print(__BLANK) print(str("{}").format(str(expectedOutput))) - print(str("")) + print(__BLANK) print(str("The actual output was...")) - print(str("")) + print(__BLANK) print(str("{}").format(str(actualOutput))) - print(str("")) + print(__BLANK) class BasicUsageTestSuite(unittest.TestCase): @@ -508,6 +508,7 @@ class BasicUsageTestSuite(unittest.TestCase): @classmethod def setUpClass(cls): + """Overides unittest.TestCase.setUpClass(cls) to setup thepython test fixture.""" cls._thepython = getPythonCommand() def setUp(self): @@ -525,7 +526,7 @@ def test_absolute_truth_and_meaning(self): self.assertTrue(True, "Insanitty Test Failed") def test_finds_python_WHEN_testing(self): - """Test case 0: Class Test-Fixture Meta Test.""" + """Test case 1: Class Test-Fixture Meta Test.""" self.test_absolute_truth_and_meaning() if (self._thepython is None) and (len(self._thepython) <= 0): self.fail(str("""No python cmd to test with!""")) diff --git a/tests/test_basic.py b/tests/test_basic.py index 76459fed..7c972699 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -68,9 +68,13 @@ def test_Does_Pass_WHEN_Using_Import_From_Syntax(self): try: from .context import multicast self.assertIsNotNone(multicast.__name__) + theResult = True if multicast.__name__ is None: theResult = False - theResult = True + if multicast.__module__ is None: + theResult = False + if multicast.__doc__ is None: + theResult = False except Exception as impErr: print(str(type(impErr))) print(str(impErr)) diff --git a/tests/test_usage.py b/tests/test_usage.py index 81ae09ec..acc2aa30 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -94,13 +94,12 @@ def test_multicast_hear_invalid_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - @unittest.expectedFailure def test_multicast_hexdump_arg_main(self): """Tests the hexdump argument for failure given future tools""" theResult = False fail_fixture = str("""multicast.__main__.useTool(HEAR, hex) == error""") try: - with self.assertRaises(NotImplementedError): + with self.assertRaises(SystemExit): self.assertIsNotNone(multicast.__main__.useTool("HEAR", ["--hex"])) theResult = True except Exception as err: From 9a415fc14c76a475d97efff0c08a7bdb0dae40c8 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 24 Feb 2022 04:00:00 -0800 Subject: [PATCH 098/135] [STYLE] fix for linter barff --- multicast/__init__.py | 2 +- multicast/__main__.py | 2 +- multicast/recv.py | 10 ++++++---- multicast/send.py | 1 - 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/multicast/__init__.py b/multicast/__init__.py index 93237cf2..0f7e4882 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -20,7 +20,7 @@ __all__ = [ """__package__""", """__module__""", """__name__""", """__version__""", """__prologue__""", - """__builtins__""", """__doc__""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", + """__doc__""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", """__MCAST_DEFAULT_TTL""", """recv""", """send""", """__main__""" ] diff --git a/multicast/__main__.py b/multicast/__main__.py index d9e97cf5..67d4b235 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -374,4 +374,4 @@ def main(*argv): __EXIT_CODE = main(sys.argv[1:]) elif (sys.argv is not None): __EXIT_CODE = main([str(__proc__), """-h"""]) - exit(__EXIT_CODE) + exit(__EXIT_CODE) \ No newline at end of file diff --git a/multicast/recv.py b/multicast/recv.py index 2a6f7078..d8b527bf 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -298,10 +298,13 @@ def hearstep(groups, port, iface=None, bind_group=None): >>> multicast.recv.hearstep(None, 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS '...' - >>> multicast.recv.hearstep([multicast.__MCAST_DEFAULT_GROUP], 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + >>> tst_fxtr = multicast.__MCAST_DEFAULT_GROUP + >>> multicast.recv.hearstep([tst_fxtr], 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS '...' - >>> multicast.recv.hearstep([multicast.__MCAST_DEFAULT_GROUP], 19991, None, multicast.__MCAST_DEFAULT_GROUP) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + >>> multicast.recv.hearstep( + ... [tst_fxtr], 19991, None, tst_fxtr + ... ) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS '...' >>> @@ -462,5 +465,4 @@ def main(*argv): >>> -""" + __epilogue__ + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ - +""" + __epilogue__ + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ + main.__doc__ diff --git a/multicast/send.py b/multicast/send.py index 1eff8e62..cbda146e 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -296,4 +296,3 @@ def main(*argv): __exit_code = 3 del e return int(__exit_code) - From 4509711530b025193251c28cbff781057355524c Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 24 Feb 2022 04:29:14 -0800 Subject: [PATCH 099/135] [STYLE][REGRESSION] fix for stickler lint barff --- multicast/__main__.py | 2 +- multicast/recv.py | 11 +++++++++-- multicast/send.py | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/multicast/__main__.py b/multicast/__main__.py index 67d4b235..d9e97cf5 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -374,4 +374,4 @@ def main(*argv): __EXIT_CODE = main(sys.argv[1:]) elif (sys.argv is not None): __EXIT_CODE = main([str(__proc__), """-h"""]) - exit(__EXIT_CODE) \ No newline at end of file + exit(__EXIT_CODE) diff --git a/multicast/recv.py b/multicast/recv.py index d8b527bf..e84beaee 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -411,7 +411,8 @@ def main(*argv): return int(__exit_code) -__doc__ = __prologue__ + """ +__doc__ = (__prologue__ + + """ Minimal Acceptance Testing: @@ -465,4 +466,10 @@ def main(*argv): >>> -""" + __epilogue__ + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ + main.__doc__ +""" + + __epilogue__ + + genSocket.__doc__ + + endSocket.__doc__ + + parseArgs.__doc__ + + hearstep.__doc__ + + main.__doc__) diff --git a/multicast/send.py b/multicast/send.py index cbda146e..bbd9e8d5 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -169,19 +169,19 @@ def parseArgs(*arguments): """Will attempt to parse the given CLI arguments. See argparse.ArgumentParser for more. - param str - arguments - the array of arguments to parse. Usually sys.argv[1:] + param str - arguments - the array of arguments to parse. (Usually sys.argv[1:]) returns argparse.Namespace - the Namespace parsed with the key-value pairs. - Minimal Acceptance Testing: + Testing: - First setup test fixtures by importing multicast. + Testcase 0: First setup test fixtures by importing multicast. >>> import multicast >>> multicast.send is not None True >>> - Testcase 0: parseArgs should return a namespace. + Testcase 1: parseArgs should return a namespace. A: Test that the multicast component is initialized. B: Test that the send component is initialized. C: Test that the send.parseArgs component is initialized. From 79c59408dec1f0baf2fb5194ba1c02faa4777489 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 24 Feb 2022 05:02:47 -0800 Subject: [PATCH 100/135] [REGRESSION] churn by linter barff --- multicast/recv.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index e84beaee..dc1089e8 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -411,8 +411,8 @@ def main(*argv): return int(__exit_code) -__doc__ = (__prologue__ - + """ +__doc__ = str( + __prologue__ + """ Minimal Acceptance Testing: @@ -466,10 +466,7 @@ def main(*argv): >>> -""" - + __epilogue__ - + genSocket.__doc__ - + endSocket.__doc__ - + parseArgs.__doc__ - + hearstep.__doc__ - + main.__doc__) +""" + __epilogue__ + str( + genSocket.__doc__ + endSocket.__doc__ + parseArgs.__doc__ + hearstep.__doc__ + ) + main.__doc__ +) From 3aaf5c82c7addd28a59775ce0202009c0cd9f2b4 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 24 Feb 2022 06:08:18 -0800 Subject: [PATCH 101/135] [CI] change coverage default to auto --- .codecov.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 17559e82..c38aa18d 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -2,11 +2,11 @@ coverage: status: project: default: - target: 95% - threshold: 0% + target: auto base: auto multicast: - target: auto + target: 95% + threshold: 0% flags: - multicast paths: @@ -29,5 +29,4 @@ flags: paths: - "multicast/*.py" - "setup.py" - joined: false carryforward: true From df07ea7a9e7f5dbc31937c0e1e75e447132d2716 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Tue, 1 Mar 2022 21:57:24 -0800 Subject: [PATCH 102/135] [CONFIG] fix for setuptools config ( closes #19 ) --- requirements.txt | 4 ++-- setup.cfg | 25 ++++++++++++++++++------- setup.py | 29 ++++++++++++++++------------- tox.ini | 2 +- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/requirements.txt b/requirements.txt index aabf1729..772afa1b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,7 @@ # struct - builtin - PSF licence argparse>=1.4.0 # argparse - builtin - PSF licence -setuptools>=38.0 +setuptools>=38.3 # virtualenv - MIT #virtualenv>=15.0.1 # six - MIT @@ -32,7 +32,7 @@ setuptools>=38.0 #pgpy>=0.4.1 tox>=3.0.0 #py>=1.4.33 -pip>=19.0 +pip>=21.0 # multicast - MIT #-e git+https://github.com/reactive-firewall/multicast.git#egg=multicast diff --git a/setup.cfg b/setup.cfg index 2f2fa061..f27d5e38 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,9 +1,9 @@ [metadata] name = multicast -version = 1.2.0 +version = 1.3.0 author = Mr. Walls author_email = reactive-firewall@users.noreply.github.com -summary = Python multicast repo for send/recv stubs +summary = Python Multicast Repo for Send/Recv Stubs. description_file = README.md long_description = file: README.md long_description_content_type = text/markdown @@ -11,6 +11,12 @@ home_page = https://github.com/reactive-firewall/multicast download_url = https://github.com/reactive-firewall/multicast.git license = MIT license_file = LICENSE.md +license_files = + LICENSE[.md]* +platform = any +project_urls = + Bug Tracker = https://github.com/reactive-firewall/multicast/issues + Changelog = https://github.com/althonos/{name}/blob/master/CHANGELOG.md [bdist_rpm] url = https://github.com/reactive-firewall/multicast.git @@ -18,16 +24,21 @@ url = https://github.com/reactive-firewall/multicast.git [bdist_wheel] universal=1 -[files] -packages = find:*.py - [options] +zip_safe = false py_modules = multicast -python_requires = >=3.7 -packages = find:*.py +test_suite = tests +python_requires = >=3.7, !=3.11.* +setup_requires = + setuptools>=38.3, + wheel scripts = multicast/__main__.py +packages = find: + [options.packages.find] +include = + multicast exclude = tests diff --git a/setup.py b/setup.py index 4c3a0d64..0506ed66 100755 --- a/setup.py +++ b/setup.py @@ -17,16 +17,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Sets up the package.""" - -__prologue__ = """Python Multicast Repo for Send/Recv Stubs.""" -"""The one-line description or summary of this program.""" - -__doc__ = __prologue__ + """ +"""Sets up the package. Minimal Acceptance Testing: - Just setup test fixtures by importing multicast. + Testcase 0: Just setup test fixtures by importing multicast. >>> import multicast >>> @@ -38,7 +33,9 @@ try: from setuptools import setup + from setuptools import config from setuptools import find_packages + from setuptools.config import read_configuration except Exception: raise NotImplementedError("""[CWE-440] Not Implemented.""") @@ -81,6 +78,10 @@ def readFile(filename): except Exception: requirements = None + +conf_dict = read_configuration("""setup.cfg""", ignore_option_errors=True) + + readme = readFile("""README.md""") """The multi-line description and/or summary of this program.""" @@ -99,24 +100,26 @@ def readFile(filename): str("""Programming Language :: Python :: 3.9"""), str("""Programming Language :: Python :: 3.8"""), str("""Programming Language :: Python :: 3.7"""), + str("""Topic :: Software Development :: Libraries :: Python Modules""") str("""Topic :: Network""") ] except Exception: class_tags = str("""Development Status :: 4 - Beta""") setup( - name="""multicast""", - version="""1.3.0""", - description=__prologue__, + name=conf_dict["""metadata"""]["""name"""], + version=conf_dict["""metadata"""]["""version"""], + description=conf_dict["""metadata"""]["""description"""], long_description=readme, long_description_content_type="""text/markdown""", zip_safe=False, include_package_data=True, install_requires=requirements, - author="""reactive-firewall""", - author_email="""reactive-firewall@users.noreply.github.com""", + author=conf_dict["""metadata"""]["""author"""], + author_email=conf_dict["""metadata"""]["""author_email"""], classifiers=class_tags, - url="""https://github.com/reactive-firewall/multicast.git""", + url=conf_dict["""metadata"""]["""url"""], + download_url=conf_dict["""metadata"""]["""download_url"""], license=SLA, packages=find_packages(exclude=("""tests""", """docs""")), ) diff --git a/tox.ini b/tox.ini index 3066c15e..27ef11b7 100644 --- a/tox.ini +++ b/tox.ini @@ -23,7 +23,7 @@ sitepackages = False recreate = True alwayscopy = True passenv = - LC_ALL="en_utf8" + LC_ALL="en_US.utf8" {[base]passenv} basepython = py27: python2.7 From c8996c2f7df963efce5410598201e6b8b366b490 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 00:32:06 -0800 Subject: [PATCH 103/135] [TESTS] extras for testing ( closes #29 ) --- .github/workflows/Tests.yml | 82 ++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 1dfee097..4d5489e9 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -150,14 +150,94 @@ jobs: run: make -j1 -f Makefile clean || true ; - name: Testing Style id: style + needs: [clean] run: make -j1 -f Makefile test-style ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; if: ${{ always() }} + needs: [clean, style] + + + EXTRATESTS: + if: ${{ success() }} + needs: [BUILD, MATS, COVERAGE] + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.9, 3.10, 3.11] + env: + OS: ${{ matrix.os }} + PYTHON_VERSION: ${{ matrix.python-version }} + LANG: "en_US.UTF-8" + CODECLIMATE_REPO_TOKEN: ${{ secrets.CODECLIMATE_TOKEN }} + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + steps: + - uses: actions/checkout@master + - name: Setup Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies for ${{ matrix.python-version }} + run: | + python -m pip install --upgrade pip setuptools wheel + python -m pip install -r ./requirements.txt ; + python -m pip install coverage ; + python -m pip install --upgrade mccabe ; + python -m pip install --upgrade pytest ; + python -m pip install --upgrade pydocstyle ; + python -m pip install --upgrade pytest-cov ; + python -m pip install --upgrade pytest-flake8 ; + python -m pip install --upgrade pytest-doctest || true ; + python -m pip install --upgrade coverage ; + - name: Install code-climate tools for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" + shell: bash + run: | + if [ $OS == ubuntu-latest ] ; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true ; fi ; + if [ $OS == ubuntu-latest ] ; then chmod +x ./cc-test-reporter 2>/dev/null || true ; fi + if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter before-build || true ; fi + - name: Install deepsource tools for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" + shell: bash + run: | + if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; + - name: Pre-Clean + id: clean-${{ github.head_ref || github.run_id }} + run: make -j1 -f Makefile clean || true ; + - name: Generate Coverage for py${{ matrix.python-version }} extra tests + if: ${{ success() }} + run: make -j1 -f Makefile test-pytest || ( echo "::error file=Makefile,title=Extras::Some Extra Tests for Python $PYTHON_VERSION Failed on $OS." && exit 0 ) ; + - name: Upload Python ${{ matrix.python-version }} coverage to Codecov + uses: codecov/codecov-action@v2 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage.xml + directory: . + flags: ${{ matrix.os }},${{ matrix.python-version }},extras + name: multicast-github-extra-${{ matrix.os }}-${{ matrix.python-version }} + verbose: true + fail_ci_if_error: false + - name: code-climate for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" + shell: bash + run: | + if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter after-build --exit-code 0 || true ; else echo "SKIP code climate" ; fi ; + - name: deepsource for ${{ matrix.python-version }} + if: ${{ runner.os }} == "Linux" + shell: bash + run: | + if [ $OS == ubuntu-latest ] ; then ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; else echo "SKIP deepsource" ; fi ; + - name: Post-Clean + id: post-${{ github.head_ref || github.run_id }} + run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} + TOX: - needs: [MATS, STYLE, COVERAGE] + if: ${{ success() }} + needs: [MATS, STYLE, COVERAGE, EXTRATESTS] runs-on: ubuntu-latest env: From f6f13275ae3b02565edec70b8e39de196ebca2c8 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 00:43:15 -0800 Subject: [PATCH 104/135] [REGRESSSION] added a missing comma ( closes #19 ) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0506ed66..bdf03080 100755 --- a/setup.py +++ b/setup.py @@ -100,7 +100,7 @@ def readFile(filename): str("""Programming Language :: Python :: 3.9"""), str("""Programming Language :: Python :: 3.8"""), str("""Programming Language :: Python :: 3.7"""), - str("""Topic :: Software Development :: Libraries :: Python Modules""") + str("""Topic :: Software Development :: Libraries :: Python Modules"""), str("""Topic :: Network""") ] except Exception: From 4684654afc07f59e7f224f2cf1207860d93aca90 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 00:57:39 -0800 Subject: [PATCH 105/135] [REGRESSSION] removed linter barf suspect ( closes #19 ) --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index bdf03080..03216139 100755 --- a/setup.py +++ b/setup.py @@ -33,7 +33,6 @@ try: from setuptools import setup - from setuptools import config from setuptools import find_packages from setuptools.config import read_configuration except Exception: From 1e76c9658dd9b795cd0db0f4643683e47e3a0b15 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 01:06:34 -0800 Subject: [PATCH 106/135] [REGRESSSION] fix for syntax-sugar MIA ( closes #29 ) --- .github/workflows/Tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 4d5489e9..66ec3516 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -150,13 +150,11 @@ jobs: run: make -j1 -f Makefile clean || true ; - name: Testing Style id: style - needs: [clean] run: make -j1 -f Makefile test-style ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; if: ${{ always() }} - needs: [clean, style] EXTRATESTS: From a4f987a5bd4e40be9af5a7e1dc8e42140b69c454 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 01:12:03 -0800 Subject: [PATCH 107/135] [REGRESSSION] fix for github actions missing syntax-sugar ( closes #29 ) --- .github/workflows/Tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 66ec3516..7010ea92 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -202,7 +202,7 @@ jobs: run: | if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; - name: Pre-Clean - id: clean-${{ github.head_ref || github.run_id }} + id: clean-extras run: make -j1 -f Makefile clean || true ; - name: Generate Coverage for py${{ matrix.python-version }} extra tests if: ${{ success() }} @@ -228,7 +228,7 @@ jobs: run: | if [ $OS == ubuntu-latest ] ; then ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; else echo "SKIP deepsource" ; fi ; - name: Post-Clean - id: post-${{ github.head_ref || github.run_id }} + id: post-extras run: make -j1 -f Makefile clean || true ; if: ${{ always() }} From 9a63e400d289e04f3d96ec634e09b9788fff2878 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 01:55:30 -0800 Subject: [PATCH 108/135] [REGRESSSION] Python 3.11 not stable at this time ( closes #29 ) --- .github/workflows/Tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 7010ea92..18cff6e1 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -164,7 +164,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.9, 3.10, 3.11] + python-version: [3.9, 3.10] env: OS: ${{ matrix.os }} PYTHON_VERSION: ${{ matrix.python-version }} From 0698978cb9ceb70fe9f719885df31877d644b66f Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 02:23:48 -0800 Subject: [PATCH 109/135] [REGRESSSION] ROLLBACK Python 3.10+ not stable at this time ( closes #29 ) --- .github/workflows/Tests.yml | 78 +------------------------------------ Makefile | 1 - 2 files changed, 1 insertion(+), 78 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 18cff6e1..b4e28694 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -157,85 +157,9 @@ jobs: if: ${{ always() }} - EXTRATESTS: - if: ${{ success() }} - needs: [BUILD, MATS, COVERAGE] - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.9, 3.10] - env: - OS: ${{ matrix.os }} - PYTHON_VERSION: ${{ matrix.python-version }} - LANG: "en_US.UTF-8" - CODECLIMATE_REPO_TOKEN: ${{ secrets.CODECLIMATE_TOKEN }} - CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} - steps: - - uses: actions/checkout@master - - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies for ${{ matrix.python-version }} - run: | - python -m pip install --upgrade pip setuptools wheel - python -m pip install -r ./requirements.txt ; - python -m pip install coverage ; - python -m pip install --upgrade mccabe ; - python -m pip install --upgrade pytest ; - python -m pip install --upgrade pydocstyle ; - python -m pip install --upgrade pytest-cov ; - python -m pip install --upgrade pytest-flake8 ; - python -m pip install --upgrade pytest-doctest || true ; - python -m pip install --upgrade coverage ; - - name: Install code-climate tools for ${{ matrix.python-version }} - if: ${{ runner.os }} == "Linux" - shell: bash - run: | - if [ $OS == ubuntu-latest ] ; then curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter || true ; fi ; - if [ $OS == ubuntu-latest ] ; then chmod +x ./cc-test-reporter 2>/dev/null || true ; fi - if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter before-build || true ; fi - - name: Install deepsource tools for ${{ matrix.python-version }} - if: ${{ runner.os }} == "Linux" - shell: bash - run: | - if [ $OS == ubuntu-latest ] ; then (curl https://deepsource.io/cli | sh) || true ; else echo "SKIP deepsource" ; fi ; - - name: Pre-Clean - id: clean-extras - run: make -j1 -f Makefile clean || true ; - - name: Generate Coverage for py${{ matrix.python-version }} extra tests - if: ${{ success() }} - run: make -j1 -f Makefile test-pytest || ( echo "::error file=Makefile,title=Extras::Some Extra Tests for Python $PYTHON_VERSION Failed on $OS." && exit 0 ) ; - - name: Upload Python ${{ matrix.python-version }} coverage to Codecov - uses: codecov/codecov-action@v2 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage.xml - directory: . - flags: ${{ matrix.os }},${{ matrix.python-version }},extras - name: multicast-github-extra-${{ matrix.os }}-${{ matrix.python-version }} - verbose: true - fail_ci_if_error: false - - name: code-climate for ${{ matrix.python-version }} - if: ${{ runner.os }} == "Linux" - shell: bash - run: | - if [ $OS == ubuntu-latest ] ; then ./cc-test-reporter after-build --exit-code 0 || true ; else echo "SKIP code climate" ; fi ; - - name: deepsource for ${{ matrix.python-version }} - if: ${{ runner.os }} == "Linux" - shell: bash - run: | - if [ $OS == ubuntu-latest ] ; then ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; else echo "SKIP deepsource" ; fi ; - - name: Post-Clean - id: post-extras - run: make -j1 -f Makefile clean || true ; - if: ${{ always() }} - - TOX: if: ${{ success() }} - needs: [MATS, STYLE, COVERAGE, EXTRATESTS] + needs: [MATS, STYLE, COVERAGE] runs-on: ubuntu-latest env: diff --git a/Makefile b/Makefile index d7ba2797..51da0d33 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,6 @@ test-style: cleanup $(QUIET)flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || $(PYTHON) -m flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || true $(QUIET)tests/check_spelling 2>/dev/null || true $(QUIET)tests/check_cc_lines 2>/dev/null || true - $(QUIET)tests/check_codecov 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." cleanup: From 76eb88e8a8f8617918cd7569bbecfee7b9a7f5bd Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 22:16:30 -0800 Subject: [PATCH 110/135] [STYLE] fix for shell lock file paths ( closes #6 + WIP on #27 ) --- .codecov.yml | 67 ++++++++++++++++++++++++++++++++++++-------- .gitignore | 2 ++ tests/check_cc_lines | 29 +++++++++++-------- tests/check_codecov | 14 +++++---- tests/check_spelling | 2 +- 5 files changed, 85 insertions(+), 29 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index c38aa18d..8793d04e 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,9 +1,22 @@ +codecov: + max_report_age: off + max_report_age: off + + coverage: + precision: 2 + range: "80...100" status: project: default: target: auto base: auto + branches: + - master + - stageing + - stable + if_ci_failed: error #success, failure, error, ignore + only_pulls: false multicast: target: 95% threshold: 0% @@ -17,16 +30,48 @@ coverage: flags: - unittests paths: - - "tests/*" + - "tests/*.py" -flags: - unittests: - paths: - - "tests/*" - carryforward: true - joined: false - multicast: - paths: - - "multicast/*.py" - - "setup.py" + +flag_management: + default_rules: # the rules that will be followed for any flag added, generally carryforward: true + statuses: + - name_prefix: project- + type: project + target: auto + threshold: 1% + - name_prefix: patch- + type: patch + target: 90% + individual_flags: # exceptions to the default rules above, stated flag by flag + - name: multicast #fill in your own flag name + paths: + - multicast/*.py #fill in your own path. Note, accepts globs, not regexes + - setup.py + carryforward: true + statuses: + - name_prefix: new + type: project + target: 51% + - name_prefix: new + type: patch + target: 90% + - name: tests + paths: + - tests/* #fill in your own path. Note, accepts globs, not regexes + carryforward: true + - name: extras + joined: false + carryforward: true + - name: unittests + paths: + - tests/*.py #fill in your own path. Note, accepts globs, not regexes + carryforward: true + - name: macos-latest + carryforward: false + - name: linux-latest + carryforward: false + - name: windows-latest + carryforward: false + joined: false diff --git a/.gitignore b/.gitignore index fc0f2370..05d9f344 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ __pycache__/ *.py[cod] *$py.class *~ +*/*~ +./**/*~ # C extensions *.so diff --git a/tests/check_cc_lines b/tests/check_cc_lines index 78c2e27a..1dcc6670 100755 --- a/tests/check_cc_lines +++ b/tests/check_cc_lines @@ -64,24 +64,31 @@ ulimit -t 600 PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" umask 137 -LOCK_FILE="/tmp/cc_line_test_script_lock" +LOCK_FILE="${TMPDIR:-/tmp}/cc_line_test_script_lock" EXIT_CODE=0 test -x $(command -v grep) || exit 126 ; +test -x $(command -v curl) || exit 126 ; +test -x $(command -v find) || exit 126 ; +test -x $(command -v git) || exit 126 ; + +function cleanup() { + rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; +} if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 + trap 'cleanup ; wait ; exit 1 ;' SIGHUP || EXIT_CODE=3 + trap 'cleanup ; wait ; exit 1 ;' SIGTERM || EXIT_CODE=4 + trap 'cleanup ; wait ; exit 1 ;' SIGQUIT || EXIT_CODE=5 # SC2173 - https://github.com/koalaman/shellcheck/wiki/SC2173 # trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGSTOP || EXIT_CODE=7 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 - trap 'rm -f ${LOCK_FILE} 2>/dev/null || true ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 + trap 'cleanup ; wait ; exit 1 ;' SIGINT || EXIT_CODE=8 + trap 'cleanup ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 + trap 'cleanup ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 else - echo Test already in progress by `head ${LOCK_FILE}` ; - false ; - exit 126 ; + echo "Check for Copyright lines already in progress by "`head ${LOCK_FILE}` ; + false ; + exit 126 ; fi # this is how test files are found: @@ -105,7 +112,7 @@ for _TEST_DOC in $(find ${_TEST_ROOT_DIR} \( -iname '*.py' -o -iname '*.txt' -o EXIT_CODE=126 else if [[ ($(grep -cF "Copyright" "${_TEST_DOC}" 2>&1 || EXIT_CODE=$? ;) -le 0) ]] ; then - echo "FAIL: ${_TEST_DOC} is missing a copyright line" ; + echo "FAIL: ${_TEST_DOC} is missing a copyright line" >&2 ; EXIT_CODE=127 fi if [[ ( $(grep -F "Copyright" "${_TEST_DOC}" 2>&1 | grep -coF "Copyright (c)" 2>&1) -le 0) ]] ; then diff --git a/tests/check_codecov b/tests/check_codecov index 06a5cf8a..0c7d87b9 100755 --- a/tests/check_codecov +++ b/tests/check_codecov @@ -64,13 +64,14 @@ ulimit -t 1200 PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${PATH}" LANG=${LANG:-"en_US"} LC_ALL="${LANG:1:5}.utf-8" -umask 027 +umask 127 -LOCK_FILE="/tmp/codecov_test_script_lock" +LOCK_FILE="${TMPDIR:-/tmp}/codecov_test_script_lock" EXIT_CODE=0 test -x $(command -v grep) || exit 126 ; test -x $(command -v curl) || exit 126 ; +test -x $(command -v gpgv) || exit 126 ; test -x $(command -v shasum) || exit 126 ; # sorry no windows support here @@ -95,7 +96,7 @@ if [[ ( $(shlock -f ${LOCK_FILE} -p $$ ) -eq 0 ) ]] ; then trap 'cleanup ; wait ; exit 1 ;' SIGABRT || EXIT_CODE=9 trap 'cleanup ; wait ; exit ${EXIT_CODE} ;' EXIT || EXIT_CODE=1 else - echo CodeCov already in progress by `head ${LOCK_FILE}` ; + echo "CodeCov already in progress by "`head ${LOCK_FILE}` ; false ; exit 126 ; fi @@ -113,7 +114,8 @@ else EXIT_CODE=1 fi -# This File MUST BE GIT-IGNORED to be SAFELY USED to store Tokens and env vars (update logic as needed) +# This File MUST BE GIT-IGNORED +# to be SAFELY USED to store Tokens and env vars (update logic as needed) if [[ ( -r ./codecov_env ) ]] ; then source ./codecov_env 2>/dev/null || true ; fi @@ -161,14 +163,14 @@ elif [[ ( -x $(command -v coverage) ) ]] ; then fi if [[ ( ${EXIT_CODE} -eq 0 ) ]] ; then - ./codecov -n "Custom Test Run" -X gcov -F ${CI_OS:-linux} || EXIT_CODE=5 ; + ./codecov -n "Custom Test Run" -X gcov -F multicast,${CI_OS:-linux}-latest -Z || EXIT_CODE=10 ; fi unset _TEST_ROOT_DIR 2>/dev/null || true ; -rm -f ${LOCK_FILE} 2>/dev/null > /dev/null || true ; wait ; rm -f ./codecov 2>/dev/null > /dev/null || true ; wait ; +rm -f ${LOCK_FILE} 2>/dev/null > /dev/null || true ; wait ; # goodbye exit ${EXIT_CODE:-255} ; diff --git a/tests/check_spelling b/tests/check_spelling index b39704c4..ecbc3b5a 100755 --- a/tests/check_spelling +++ b/tests/check_spelling @@ -64,7 +64,7 @@ ulimit -t 600 PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" umask 137 -LOCK_FILE="/tmp/spelling_test_script_lock" +LOCK_FILE="${TMPDIR:-/tmp}/spelling_test_script_lock" EXIT_CODE=0 # exit fast if command is missing From 8643d4d3a793fffc298e3eb78c32f956b2e55cf2 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Wed, 2 Mar 2022 22:19:37 -0800 Subject: [PATCH 111/135] [REGRESSION] typO fix --- .codecov.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.codecov.yml b/.codecov.yml index 8793d04e..0550f2c4 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,6 +1,5 @@ codecov: max_report_age: off - max_report_age: off coverage: From 1ddaa5a59bb0987aa739e555307fcd2b5050a0b9 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 3 Mar 2022 00:00:24 -0800 Subject: [PATCH 112/135] [STYLE] Renamed tests by new convention ( closes #34 ) --- tests/context.py | 65 +++++++++++++++++++++++--- tests/test_usage.py | 111 ++++++++++++++++++++++++++++---------------- 2 files changed, 129 insertions(+), 47 deletions(-) diff --git a/tests/context.py b/tests/context.py index e8f37854..483b0d25 100644 --- a/tests/context.py +++ b/tests/context.py @@ -301,13 +301,13 @@ def checkPythonFuzzing(args=[None], stderr=None): """function for backend subprocess check_output command""" theOutput = None try: - if args is None or args is [None]: + if args is None or args is [None]: # pragma: no branch theOutput = subprocess.check_output(["exit 1 ; #"]) else: if str("coverage") in args[0]: args = checkCovCommand(args) theOutput = subprocess.check_output(args, stderr=stderr) - except Exception as err: + except BaseException as err: # pragma: no branch theOutput = None raise RuntimeError(err) theOutput = checkStrOrByte(theOutput) @@ -315,6 +315,57 @@ def checkPythonFuzzing(args=[None], stderr=None): def debugBlob(blob=None): + """Helper function to debug unexpected outputs. + + Especialy usefull for cross-python testing where output may differ + yet may be from the same logical data. + + Meta Testing: + + First setup test fixtures by importing test context. + + >>> import tests.context + >>> + + >>> norm_fixture = "Example Sample" + >>> othr_fixture = \"""'Example Sample'\""" + >>> + + Testcase 1: function should have a output. + + >>> debugBlob(norm_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + String: + " + Example Sample + " + + Data: + " + 'Example Sample' + " + + True + >>> + + Testcase 2: function should have a output even with bad input. + + >>> debugBlob(othr_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + String: + " + ...Example Sample... + " + + Data: + " + ...'Example Sample'... + " + + True + >>> + + """ try: print(__BLANK) print(str("String:")) @@ -333,8 +384,7 @@ def debugBlob(blob=None): def debugtestError(someError): - """ - Helper function to debug unexpected outputs. + """Helper function to debug unexpected outputs. Meta Testing: @@ -384,7 +434,9 @@ def debugtestError(someError): def check_exec_command_has_output(test_case, someArgs): """Test case for command output != None. - returns True if has output and False otherwise.""" + + returns True if has output and False otherwise. + """ theResult = False fail_msg_fixture = str("""Expecting output: CLI test had no output.""") try: @@ -407,8 +459,7 @@ def check_exec_command_has_output(test_case, someArgs): def debugUnexpectedOutput(expectedOutput, actualOutput, thepython): - """ - Helper function to debug unexpected outputs. + """Helper function to debug unexpected outputs. Meta Testing: diff --git a/tests/test_usage.py b/tests/test_usage.py index acc2aa30..4eb2311d 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -17,6 +17,33 @@ # See the License for the specific language governing permissions and # limitations under the License. + +""" +Tests of integration by usage. + + + Meta + tests.test_usage.BasicIntegrationTestSuite + + Integration Tests - Fixtures: + + Test fixtures by importing test context. + + >>> import tests.test_usage as test_usage + >>> import tests + >>> + + >>> tests.test_usage.MulticastTestSuite #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + >>> + + >>> tests.test_usage.BasicIntegrationTestSuite #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + + >>> + +""" + + try: import sys if sys.__name__ is None: # pragma: no branch @@ -48,7 +75,9 @@ class MulticastTestSuite(context.BasicUsageTestSuite): __module__ = """tests.test_usage""" - def test_multicast_insane_none(self): + __name__ = """tests.test_usage.MulticastTestSuite""" + + def test_aborts_WHEN_calling_multicast_GIVEN_invalid_tools(self): """Tests the imposible state for CLI tools given bad tools""" theResult = False fail_fixture = str("""multicast.__main__.useTool(JUNK) == error""") @@ -62,7 +91,7 @@ def test_multicast_insane_none(self): theResult = False self.assertTrue(theResult, fail_fixture) - def test_multicast_message_arg_main(self): + def test_say_is_stable_WHEN_calling_multicast_GIVEN_say_tool(self): """Tests the message argument for expected syntax given simple args""" theResult = False fail_fixture = str("""multicast.__main__.useTool(SAY, message) == error""") @@ -77,7 +106,7 @@ def test_multicast_message_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - def test_multicast_hear_invalid_arg_main(self): + def test_hear_aborts_WHEN_calling_multicast_GIVEN_invalid_args(self): """Tests the message argument for failure given invalid input""" theResult = False fail_fixture = str("""multicast.__main__.useTool(HEAR, junk) != 2""") @@ -94,7 +123,7 @@ def test_multicast_hear_invalid_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - def test_multicast_hexdump_arg_main(self): + def test_hear_aborts_WHEN_calling_multicast_GIVEN_invalid_tool(self): """Tests the hexdump argument for failure given future tools""" theResult = False fail_fixture = str("""multicast.__main__.useTool(HEAR, hex) == error""") @@ -108,7 +137,7 @@ def test_multicast_hexdump_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - def test_multicast_invalid_main(self): + def test_noop_stable_WHEN_calling_multicast_GIVEN_noop_args(self): """Tests the NOOP state for multicast given bad input""" theResult = False fail_fixture = str("""multicast.__main__.main(NOOP) == empty""") @@ -121,7 +150,7 @@ def test_multicast_invalid_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - def test_multicast_help_arg_main(self): + def test_help_works_WHEN_calling_multicast_GIVEN_help_tool(self): """Tests the HELP argument for help usage""" theResult = False fail_fixture = str("""multicast.__main__.useTool(HELP, []) == error""") @@ -134,7 +163,7 @@ def test_multicast_help_arg_main(self): theResult = False self.assertTrue(theResult, fail_fixture) - def test_multicast_message_send_recv(self): + def test_hear_works_WHEN_say_works(self): """Tests the basic send and recv test""" theResult = False fail_fixture = str("""SAY --> HEAR == error""") @@ -142,7 +171,7 @@ def test_multicast_message_send_recv(self): _fixture_SAY_args = [ """--port=19991""", """--mcast-group='224.0.0.1'""", - """--message='test'""" + """--message='test message'""" ] _fixture_HEAR_args = [ """--port=19991""", @@ -160,6 +189,7 @@ def test_multicast_message_send_recv(self): raise unittest.SkipTest(fail_fixture) p.join() self.assertIsNotNone(p.exitcode) + self.assertEqual(int(p.exitcode), int(0)) theResult = True except Exception as err: context.debugtestError(err) @@ -169,24 +199,13 @@ def test_multicast_message_send_recv(self): self.assertTrue(theResult, fail_fixture) -def debugIfNoneResult(thepython, theArgs, theOutput): - """In case you need it.""" - try: - if (str(theOutput) is not None): - theResult = True - else: - theResult = False - context.debugUnexpectedOutput(theOutput, None, thepython) - except Exception: - theResult = False - return theResult - - class BasicIntegrationTestSuite(context.BasicUsageTestSuite): """Basic functional test cases.""" __module__ = """tests.test_usage""" + __name__ = """tests.test_usage.BasicIntegrationTestSuite""" + def setUp(self): super(self.__class__, self).setUp() if (self._thepython is None): @@ -263,16 +282,8 @@ def test_prints_version_WHEN_called_GIVEN_version_argument(self): str("--version") ] theOutputtxt = context.checkPythonCommand(args, stderr=subprocess.STDOUT) - # now test it - try: - if isinstance(theOutputtxt, bytes): - theOutputtxt = theOutputtxt.decode('utf8') - except UnicodeDecodeError: - theOutputtxt = str(repr(bytes(theOutputtxt))) - # ADD REAL VERSION TEST HERE - theResult = debugIfNoneResult(self._thepython, args, theOutputtxt) - # or simply: - self.assertIsNotNone(theOutputtxt) + context.check_exec_command_has_output(self, args) + theResult = (theOutputtxt is not None) except Exception as err: context.debugtestError(err) err = None @@ -312,7 +323,7 @@ def test_Usage_Error_WHEN_the_help_command_is_called(self): theResult = False self.assertTrue(theResult, str("""Could Not find usage from multicast --help""")) - def test_profile_template_case(self): + def test_profile_WHEN_the_noop_command_is_called(self): """Test case template for profiling""" theResult = False if (self._thepython is not None): @@ -345,9 +356,35 @@ def test_profile_template_case(self): theResult = False assert theResult - def test_invalid_Error_WHEN_cli_called_GIVEN_bad_input(self): + def test_stable_WHEN_the_noop_command_is_called(self): """Test case template for profiling""" theResult = False + if (self._thepython is not None): + try: + for test_case in ["NOOP"]: + args = [ + str(self._thepython), + str("-m"), + str("multicast"), + str("{}").format( + str( + test_case + ) + ) + ] + context.checkPythonFuzzing(args, stderr=None) + # now test it + theResult = True + except Exception as err: + context.debugtestError(err) + err = None + del err + theResult = False + self.assertTrue(theResult, str("""Could Not handle multicast NOOP""")) + + def test_invalid_Error_WHEN_cli_called_GIVEN_bad_input(self): + """Test case template for invalid input to multicast CLI.""" + theResult = False if (self._thepython is not None): try: for test_case in ["BAdInPut", "1", "exit"]: @@ -362,17 +399,11 @@ def test_invalid_Error_WHEN_cli_called_GIVEN_bad_input(self): ) ] theOutputtxt = context.checkPythonCommand(args, stderr=subprocess.STDOUT) - # now test it - try: - if isinstance(theOutputtxt, bytes): - theOutputtxt = theOutputtxt.decode('utf8') - except UnicodeDecodeError: - theOutputtxt = str(repr(bytes(theOutputtxt))) - theResult = debugIfNoneResult(self._thepython, args, theOutputtxt) # or simply: self.assertIsNotNone(theOutputtxt) self.assertIn(str("invalid choice:"), str(theOutputtxt)) self.assertIn(str(test_case), str(theOutputtxt)) + theResult = True except Exception as err: context.debugtestError(err) err = None From a0e44537a761186ac01d197a6f791d55551581e5 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 3 Mar 2022 00:08:38 -0800 Subject: [PATCH 113/135] [REGRESSION] Fixes for regressions in config ( closes #34 ) --- .codecov.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 0550f2c4..954881e7 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -61,7 +61,6 @@ flag_management: - tests/* #fill in your own path. Note, accepts globs, not regexes carryforward: true - name: extras - joined: false carryforward: true - name: unittests paths: @@ -73,4 +72,3 @@ flag_management: carryforward: false - name: windows-latest carryforward: false - joined: false From 241922ef5caefc4dba124ebcdaef6f482cb35e69 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 3 Mar 2022 00:24:49 -0800 Subject: [PATCH 114/135] [REGRESSION] Fixes for regressions and some cli argument wrangling ( closes #28 + re-closes #34 ) --- tests/context.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/context.py b/tests/context.py index 483b0d25..65bef648 100644 --- a/tests/context.py +++ b/tests/context.py @@ -245,17 +245,18 @@ def checkCovCommand(args=[None]): if sys.__name__ is None: # pragma: no branch raise ImportError("[CWE-758] Failed to import system. WTF?!!") if str("coverage") in args[0]: - i = 0 + i = 1 if str("{} -m coverage").format(str(sys.executable)) in str(args[0]): # pragma: no branch args[0] = str(sys.executable) args.insert(1, str("-m")) args.insert(2, str("coverage")) - i = 2 + i += 2 else: # pragma: no branch args[0] = str(getCoverageCommand()) - args.insert(i + 1, str("run")) - args.insert(i + 2, str("-p")) - args.insert(i + 3, str("--source=multicast")) + extra_args = ["""run""", """-p""", """--source=multicast"""] + for k in range(0, len(extra_args)): + offset = i + k + args.insert(offset, extra_args[k]) return args From ea6c32648c7971934bcfabc73d1541dcbe06e9f1 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 3 Mar 2022 00:37:30 -0800 Subject: [PATCH 115/135] [DOCUMENTAION] refactor some comments as per discussion ( updates #33 ) --- multicast/recv.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index dc1089e8..4186cbfb 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -133,8 +133,9 @@ def genSocket(): """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - # allow reuse of socket (to allow another instance of python running this - # script binding to the same ip/port) + """Allows reuse of socket (to allow another instance of python running this + script binding to the same ip/port). + """ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(20) return sock From d2ed5ec6027775ac46225384ce96d841c65124f5 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Thu, 3 Mar 2022 02:21:58 -0800 Subject: [PATCH 116/135] [TESTS] refactor some comments as per linter ( updates #33 ) --- multicast/__init__.py | 4 ++-- multicast/recv.py | 2 +- tests/__init__.py | 35 +++++++++++++++++------------------ tests/context.py | 9 ++++----- tests/test_basic.py | 20 ++++++++------------ tests/test_usage.py | 2 ++ 6 files changed, 34 insertions(+), 38 deletions(-) diff --git a/multicast/__init__.py b/multicast/__init__.py index 0f7e4882..93448a29 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -199,9 +199,8 @@ """ -global __MCAST_DEFAULT_TTL -__MCAST_DEFAULT_TTL = 20 +global __MCAST_DEFAULT_TTL """ Arbitrary TTL time to live to use by default, though any small (2-126) TTL would work. @@ -253,6 +252,7 @@ import socket if socket.__name__ is None: raise ImportError("FAIL: we could not import socket. ABORT.") + __MCAST_DEFAULT_TTL = int(socket.IP_DEFAULT_MULTICAST_TTL) except Exception as err: raise ImportError(err) diff --git a/multicast/recv.py b/multicast/recv.py index 4186cbfb..01f1e5ea 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -137,7 +137,7 @@ def genSocket(): script binding to the same ip/port). """ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(20) + sock.settimeout(socket.IP_DEFAULT_MULTICAST_TTL) return sock diff --git a/tests/__init__.py b/tests/__init__.py index 7cc9de47..5e22d5ed 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -17,22 +17,21 @@ # limitations under the License. -__module__ = """tests""" +"""Multicast Testing Module. -__name__ = """tests""" + Testing: -__doc__ = """Multicast Testing Module. + Testcase 0: Load tests fixtures - Testing: + >>> import tests as _tests + >>> _tests.__module__ is not None + True - Testcase 0: Load tests fixtures - >>> import tests as _tests - >>> _tests.__module__ is not None - True +""" -""" +__module__ = """tests""" try: import sys @@ -135,20 +134,20 @@ def load_tests(loader, tests, pattern): - """Loads the tests from the project and then attempts to load the doctests too. + """Will Load the tests from the project and then attempts to load the doctests too. - Testing: + Testing: - Testcase 0: Load test fixtures + Testcase 0: Load test fixtures - >>> import tests as _tests - >>> + >>> import tests as _tests + >>> - Testcase 1: Load test fixtures + Testcase 1: Load test fixtures - >>> import tests as _tests - >>> _tests.load_tests is not None - True + >>> import tests as _tests + >>> _tests.load_tests is not None + True """ try: diff --git a/tests/context.py b/tests/context.py index 65bef648..b0d84f7a 100644 --- a/tests/context.py +++ b/tests/context.py @@ -254,9 +254,10 @@ def checkCovCommand(args=[None]): else: # pragma: no branch args[0] = str(getCoverageCommand()) extra_args = ["""run""", """-p""", """--source=multicast"""] - for k in range(0, len(extra_args)): + # PEP-279 - see https://www.python.org/dev/peps/pep-0279/ + for k, ktem in enumerate(extra_args): offset = i + k - args.insert(offset, extra_args[k]) + args.insert(offset, ktem) return args @@ -564,8 +565,7 @@ def setUpClass(cls): cls._thepython = getPythonCommand() def setUp(self): - """ - Overides unittest.TestCase.setUp(unittest.TestCase). + """Overides unittest.TestCase.setUp(unittest.TestCase). Defaults is to skip test if class is missing thepython test fixture. """ if (self._thepython is None) and (len(self._thepython) <= 0): @@ -579,7 +579,6 @@ def test_absolute_truth_and_meaning(self): def test_finds_python_WHEN_testing(self): """Test case 1: Class Test-Fixture Meta Test.""" - self.test_absolute_truth_and_meaning() if (self._thepython is None) and (len(self._thepython) <= 0): self.fail(str("""No python cmd to test with!""")) self.test_absolute_truth_and_meaning() diff --git a/tests/test_basic.py b/tests/test_basic.py index 7c972699..469a4932 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -17,18 +17,8 @@ # See the License for the specific language governing permissions and # limitations under the License. - __module__ = """tests""" - -try: - import sys - if sys.__name__ is None: # pragma: no branch - raise ImportError("[CWE-440] OMG! we could not import sys! ABORT. ABORT.") -except Exception as err: # pragma: no branch - raise ImportError(err) - - try: try: import context @@ -40,6 +30,7 @@ raise ImportError("[CWE-758] Failed to import context") else: from context import unittest as unittest + from context import sys as _sys except Exception: # pragma: no branch raise ImportError("[CWE-758] Failed to import test context") @@ -118,10 +109,15 @@ def test_None_WHEN_Nothing(self): self.assertIsNone(None) # define new tests below - @unittest.skipUnless(sys.platform.startswith("linux"), "This test example requires linux") + @unittest.skipUnless(_sys.platform.startswith("linux"), "This test example requires linux") def test_Skip_UNLESS_linux_only(self): """Linux is the test.""" - self.assertTrue(sys.platform.startswith("linux")) + self.assertTrue(_sys.platform.startswith("linux")) + + @unittest.skipUnless(_sys.platform.startswith("darwin"), "This test example requires macOS") + def test_Skip_UNLESS_darwin_only(self): + """MacOS is the test.""" + self.assertTrue(_sys.platform.startswith("darwin")) # leave this part diff --git a/tests/test_usage.py b/tests/test_usage.py index 4eb2311d..f212661c 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -43,6 +43,8 @@ """ +__module__ = """tests""" + try: import sys From 3b2e37f9e895fbb21991d6f18bf275e255e5161b Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 4 Mar 2022 02:11:56 -0800 Subject: [PATCH 117/135] [REGRESSION] fixing CI (unstable) --- .coveragerc | 10 ++++--- multicast/__init__.py | 10 +++---- multicast/__main__.py | 10 +++---- multicast/recv.py | 14 ++++----- multicast/send.py | 18 +++++++---- requirements.txt | 4 +-- setup.cfg | 7 +++-- tests/profiling.py | 69 ++++++++++++++++++++++++++++++++++++++----- tests/test_basic.py | 8 ++--- 9 files changed, 106 insertions(+), 44 deletions(-) diff --git a/.coveragerc b/.coveragerc index b4a35549..781a31f5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -17,14 +17,13 @@ exclude_lines = raise NotImplementedError raise ImportError except subprocess.CalledProcessError - except IOError - except OSError + except ..Error # don't complain about sys.modules sys.modules not in sys.modules: # Don't complain if non-runnable code isn't run: if __name__ in u'__main__': - if __name__ in '__main__': + if __name__ .. .__main__.: if __sys_path__ not in sys.path: os.abort() exit(0) @@ -32,12 +31,15 @@ exclude_lines = partial_branches = # Have to re-enable the standard pragma rules pragma: no branch + finally: except unittest.SkipTest # Don't complain if non-runnable code isn't run: if __name__ in u'__main__': if __name__ in '__main__': if __sys_path__ not in sys.path: - # not in sys.modules: + # don't complain about sys.modules + sys.modules + not in sys.modules: if context.__name__ is None: if 'os' not in sys.modules: if 'os.path' not in sys.modules: diff --git a/multicast/__init__.py b/multicast/__init__.py index 93448a29..f8668fc5 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -155,7 +155,7 @@ """ Arbitrary port to use by default, though any dynamic and free port would work. - Testing: + Minimal Testing: First setup test fixtures by importing multicast. @@ -180,7 +180,7 @@ """ Arbitrary group to use by default, though any mcst grp would work. - Testing: + Minimal Testing: First setup test fixtures by importing multicast. @@ -204,7 +204,7 @@ """ Arbitrary TTL time to live to use by default, though any small (2-126) TTL would work. - Testing: + Minimal Testing: First setup test fixtures by importing multicast. @@ -291,10 +291,10 @@ else: # pragma: no branch __main__ = sys.modules["""multicast.__main__"""] except Exception: - from . import __main__ as __main__ + import multicast.__main__ as __main__ -if __name__ in '__main__': +if __name__ == '__main__': __EXIT_CODE = 2 if __main__.__name__ is None: raise ImportError(str("Failed to open multicast")) diff --git a/multicast/__main__.py b/multicast/__main__.py index d9e97cf5..fdd601fd 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -106,13 +106,13 @@ try: - if 'multicast.__version__' not in sys.modules: - from . import __version__ as __version__ + if 'multicast' not in sys.modules: + from . import multicast as multicast else: # pragma: no branch - __version__ = sys.modules["""multicast.__version__"""] + multicast = sys.modules["""multicast"""] except Exception as importErr: del importErr - import multicast.__version__ as __version__ + import multicast as multicast try: @@ -238,7 +238,7 @@ def buildArgs(): '-V', '--version', action='version', version=str( "%(prog)s {version}" - ).format(version=str(__version__)) + ).format(version=str(multicast.__version__)) ) parser.add_argument( 'some_task', nargs='?', choices=TASK_OPTIONS.keys(), diff --git a/multicast/recv.py b/multicast/recv.py index 01f1e5ea..50ba3752 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -65,10 +65,10 @@ try: import sys + import argparse import unicodedata import socket import struct - import argparse depends = [ unicodedata, socket, struct, argparse ] @@ -85,13 +85,13 @@ try: - if 'multicast.__MCAST_DEFAULT_PORT' not in sys.modules: - from . import __MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT + if 'multicast' not in sys.modules: + from . import multicast as multicast else: # pragma: no branch - __MCAST_DEFAULT_PORT = sys.modules["""multicast.__MCAST_DEFAULT_PORT"""] -except Exception as importErr: # pragma: no branch + multicast = sys.modules["""multicast"""] +except Exception as importErr: del importErr - import multicast.__MCAST_DEFAULT_PORT as __MCAST_DEFAULT_PORT + import multicast as multicast def genSocket(): @@ -246,7 +246,7 @@ def parseArgs(arguments=None): description=__prologue__, epilog=__epilogue__ ) - parser.add_argument('--port', type=int, default=__MCAST_DEFAULT_PORT) + parser.add_argument('--port', type=int, default=multicast.__MCAST_DEFAULT_PORT) parser.add_argument( '--join-mcast-groups', default=[], nargs='*', help="""multicast groups (ip addrs) to listen to join.""" diff --git a/multicast/send.py b/multicast/send.py index bbd9e8d5..ae1fe726 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -138,10 +138,11 @@ try: import sys - import socket import argparse + import unicodedata + import socket depends = [ - socket, argparse + unicodedata, socket, argparse ] for unit in depends: try: @@ -210,8 +211,8 @@ def parseArgs(*arguments): parser.add_argument("""--port""", type=int, default=multicast.__MCAST_DEFAULT_PORT) parser.add_argument("""--mcast-group""", default=multicast.__MCAST_DEFAULT_GROUP) parser.add_argument( - """--message""", dest="""message""", - default=str("""PING from multicast_send.py: group: {group}, port: {port}""") + """--message""", nargs='+', dest="""message""", + default=str("""PING from {name}: group: {group}, port: {port}""") ) return parser.parse_args(*arguments) @@ -286,7 +287,14 @@ def main(*argv): __exit_code = 1 try: args = parseArgs(*argv) - saystep(args.mcast_group, int(args.port), args.message) + _payload = str(unicodedata.lookup("""SOFT HYPHEN""")).join( + [chunk for chunk in args.message] + ).format( + name=str(__name__), + group=str(args.mcast_group), + port=int(args.port) + ) + saystep(args.mcast_group, int(args.port), _payload) __exit_code = 0 except argparse.ArgumentError: # pragma: no branch print('Input has an Argument Error') diff --git a/requirements.txt b/requirements.txt index 772afa1b..150b7498 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,14 +23,14 @@ # struct - builtin - PSF licence argparse>=1.4.0 # argparse - builtin - PSF licence -setuptools>=38.3 +setuptools>=45.0 # virtualenv - MIT #virtualenv>=15.0.1 # six - MIT #six>=1.0.0 # pgpy - BSD 3-Clause licensed #pgpy>=0.4.1 -tox>=3.0.0 +#tox>=3.0.0 #py>=1.4.33 pip>=21.0 # multicast - MIT diff --git a/setup.cfg b/setup.cfg index f27d5e38..1aeffbd5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,10 +13,10 @@ license = MIT license_file = LICENSE.md license_files = LICENSE[.md]* + platform = any project_urls = Bug Tracker = https://github.com/reactive-firewall/multicast/issues - Changelog = https://github.com/althonos/{name}/blob/master/CHANGELOG.md [bdist_rpm] url = https://github.com/reactive-firewall/multicast.git @@ -30,8 +30,9 @@ py_modules = multicast test_suite = tests python_requires = >=3.7, !=3.11.* setup_requires = - setuptools>=38.3, - wheel + setuptools>=45.0.0 + wheel>=0.37.0 + scripts = multicast/__main__.py packages = find: diff --git a/tests/profiling.py b/tests/profiling.py index 037198ef..68ae2f57 100644 --- a/tests/profiling.py +++ b/tests/profiling.py @@ -109,7 +109,34 @@ def __exit__(self, type, value, traceback): def do_time_profile(func, timer_name="time_profile"): - """Runs a function with a timer""" + """Runs a function with a timer. + + Time Testing: + + First some test fixtures: + + >>> import tests.context as context + >>> from context import profiling as profiling + >>> + + Testcase 0: test the time_profile. + + >>> def doWork(): + ... \"""Does some work.\""" + ... for i in range(0, 42): + ... print(str("Do Task {}").format(int(i))) + >>> + >>> profiling.do_time_profile( + ... doWork, + ... timer_name=str("work time test") + ... )() #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + work...Start Timer... + ...Do Task... + work...Stop Timer... + work...took ... seconds + >>> + + """ import functools @functools.wraps(func) @@ -126,7 +153,36 @@ def timer_profile_func(*args, **kwargs): def do_cprofile(func): - """use built-in profiler to profile.""" + """Use built-in profiler to profile. + + Time Testing: + + First some test fixtures: + + >>> import tests.context as context + >>> from context import profiling as profiling + >>> + + Testcase 0: test the time_profile. + + >>> def doWork(): + ... \"""Does some work.\""" + ... for i in range(0, 42): + ... print(str("Do Task {}").format(int(i))) + >>> + >>> profiling.do_cprofile( + ... doWork + ... )() #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS + Do Task 0...Do Task 10...Do Task 20...Do Task 30...Do Task 40... + ...function calls in ... seconds...Ordered by: standard name... + ...ncalls tottime percall cumtime percall filename:lineno(function)... + ...<...>:1(doWork)...{built-in method builtins.print}... + + + >>> + + + """ def profiled_func(*args, **kwargs): profile = cProfile.Profile() try: @@ -142,7 +198,7 @@ def profiled_func(*args, **kwargs): try: # noqa from line_profiler import LineProfiler - def do_profile(follow=None): + def do_profile(follow=None): # pragma: no cover if follow is None: follow = [] @@ -160,7 +216,7 @@ def profiled_func(*args, **kwargs): return profiled_func return inner -except ImportError: # pragma: no branch +except ImportError: # pragma: no cover def do_profile(follow=None): "Helpful if you accidentally leave in production!" if follow is None: @@ -173,16 +229,15 @@ def nothing(*args, **kwargs): return inner -def main(argv=None): +def main(argv=None): # pragma: no cover """The Main Event makes no sense to profiling.""" raise NotImplementedError("CRITICAL - test profiling main() not implemented. yet?") -if __name__ in '__main__': # pragma: no branch +if __name__ in '__main__': # pragma: no cover exitcode = 3 try: exitcode = main(sys.argv[1:]) finally: exit(exitcode) - diff --git a/tests/test_basic.py b/tests/test_basic.py index 469a4932..7a2016fb 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -59,13 +59,9 @@ def test_Does_Pass_WHEN_Using_Import_From_Syntax(self): try: from .context import multicast self.assertIsNotNone(multicast.__name__) + self.assertIsNotNone(multicast.__module__) + self.assertIsNotNone(multicast.__doc__) theResult = True - if multicast.__name__ is None: - theResult = False - if multicast.__module__ is None: - theResult = False - if multicast.__doc__ is None: - theResult = False except Exception as impErr: print(str(type(impErr))) print(str(impErr)) From 8684d7d3503e39b66cdeba62d5bd8dc7425c5f82 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Fri, 4 Mar 2022 03:00:21 -0800 Subject: [PATCH 118/135] [STYLE] refactor as per linter barf --- multicast/recv.py | 6 +++--- multicast/send.py | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/multicast/recv.py b/multicast/recv.py index 50ba3752..0acd3fa4 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -97,6 +97,9 @@ def genSocket(): """Will generate an unbound socket.socket object ready to receive network traffic. + Implementation allows reuse of socket (to allow another instance of python running + this script binding to the same ip/port). + Minimal Acceptance Testing: First setup test fixtures by importing multicast. @@ -133,9 +136,6 @@ def genSocket(): """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - """Allows reuse of socket (to allow another instance of python running this - script binding to the same ip/port). - """ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(socket.IP_DEFAULT_MULTICAST_TTL) return sock diff --git a/multicast/send.py b/multicast/send.py index ae1fe726..779e2d52 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -230,9 +230,7 @@ def saystep(group, port, data): try: sock.close() except OSError: # pragma: no branch - False - sock = None - + sock = None def main(*argv): """Will handle the Main Event from multicast.__main__ when called. From aa4854c78b9d7a3ada18238b5a8f6884bdafd032 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 5 Mar 2022 23:05:42 -0800 Subject: [PATCH 119/135] [CONFIG] Fix for Codecov.yml patch status setting ( closes #36 ) --- .codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codecov.yml b/.codecov.yml index 954881e7..67a64eee 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -42,7 +42,7 @@ flag_management: threshold: 1% - name_prefix: patch- type: patch - target: 90% + target: 50% individual_flags: # exceptions to the default rules above, stated flag by flag - name: multicast #fill in your own flag name paths: From 9c474b018c3d74ff412f4ce3d5100c4868bc8132 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sat, 5 Mar 2022 23:24:37 -0800 Subject: [PATCH 120/135] [STYLE] cleanup some style fixes from churn-session --- multicast/send.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/multicast/send.py b/multicast/send.py index 779e2d52..f39d7ec8 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -232,6 +232,7 @@ def saystep(group, port, data): except OSError: # pragma: no branch sock = None + def main(*argv): """Will handle the Main Event from multicast.__main__ when called. @@ -285,9 +286,9 @@ def main(*argv): __exit_code = 1 try: args = parseArgs(*argv) - _payload = str(unicodedata.lookup("""SOFT HYPHEN""")).join( - [chunk for chunk in args.message] - ).format( + _payload = str( + unicodedata.lookup("""SOFT HYPHEN""") + ).join(list(args.message)).format( name=str(__name__), group=str(args.mcast_group), port=int(args.port) From 65468c58ddd41a985413771a4aa25ebbdd9d088f Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 00:18:52 -0800 Subject: [PATCH 121/135] [REGRESSION] Regression Fix for Codecov.yml status settings ( closes #36 ) --- .codecov.yml | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 67a64eee..299bd363 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -6,6 +6,8 @@ coverage: precision: 2 range: "80...100" status: + default_rules: + flag_coverage_not_uploaded_behavior: exclude project: default: target: auto @@ -18,28 +20,30 @@ coverage: only_pulls: false multicast: target: 95% - threshold: 0% + threshold: 1% flags: - multicast paths: - - "multicast/*.py" + - "multicast/" - "setup.py" + - "!tests/" unittests: target: 80% + threshold: 5% flags: - unittests paths: - - "tests/*.py" + - "tests/" flag_management: default_rules: # the rules that will be followed for any flag added, generally - carryforward: true + carryforward: false statuses: - name_prefix: project- type: project target: auto - threshold: 1% + threshold: 0% - name_prefix: patch- type: patch target: 50% @@ -50,25 +54,15 @@ flag_management: - setup.py carryforward: true statuses: - - name_prefix: new - type: project - target: 51% - - name_prefix: new - type: patch + - type: project target: 90% - name: tests paths: - - tests/* #fill in your own path. Note, accepts globs, not regexes - carryforward: true - - name: extras + - tests/check_* #fill in your own path. Note, accepts globs, not regexes + - tests/*.py #fill in your own path. Note, accepts globs, not regexes + - "!multicast/" carryforward: true - name: unittests paths: - - tests/*.py #fill in your own path. Note, accepts globs, not regexes - carryforward: true - - name: macos-latest - carryforward: false - - name: linux-latest - carryforward: false - - name: windows-latest - carryforward: false + - tests/ #fill in your own path. Note, accepts globs, not regexes + carryforward: true \ No newline at end of file From 3b2ff35999d2c26238f1f1638e5ad6e7281c6165 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 00:35:57 -0800 Subject: [PATCH 122/135] [REGRESSION] refactor for brain-dead windows network stack --- multicast/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/multicast/__init__.py b/multicast/__init__.py index f8668fc5..4f9ae19f 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -252,7 +252,10 @@ import socket if socket.__name__ is None: raise ImportError("FAIL: we could not import socket. ABORT.") - __MCAST_DEFAULT_TTL = int(socket.IP_DEFAULT_MULTICAST_TTL) + if sys.platform.startswith("darwin") or sys.platform.startswith("linux"): # pragma: no-branch + __MCAST_DEFAULT_TTL = int(socket.IP_DEFAULT_MULTICAST_TTL) + else: + __MCAST_DEFAULT_TTL = int(20) except Exception as err: raise ImportError(err) From c76338b1e097688cec12fe34676d52ccda55c80d Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 00:45:05 -0800 Subject: [PATCH 123/135] [REGRESSION] refactor for brain-dead windows network stack ( part 2 ) --- multicast/recv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multicast/recv.py b/multicast/recv.py index 0acd3fa4..d9bc5462 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -137,7 +137,7 @@ def genSocket(): """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(socket.IP_DEFAULT_MULTICAST_TTL) + sock.settimeout(multicast.__MCAST_DEFAULT_TTL) return sock From 6f322b1113b5d84030b35e455d7ead70bdfbcf35 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 04:10:02 -0800 Subject: [PATCH 124/135] [CONFIG] fix for builds and purges --- Makefile | 12 ++++++++---- setup.cfg | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 51da0d33..1b98a71e 100644 --- a/Makefile +++ b/Makefile @@ -78,15 +78,17 @@ PHONY: must_be_root cleanup build: $(QUIET)$(ECHO) "INFO: No need to build. Try make -f Makefile install" - $(QUIET)$(PYTHON) ./setup.py build + $(QUIET)$(PYTHON) setup.py build + $(QUIET)$(PYTHON) setup.py bdist_wheel --universal + $(QUITE)$(WAIT) $(QUIET)$(ECHO) "build DONE." init: $(QUIET)$(ECHO) "$@: Done." -install: must_be_root +install: build must_be_root $(QUIET)$(PYTHON) -m pip install --upgrade pip setuptools wheel || true - $(QUIET)$(PYTHON) -m pip install "git+https://github.com/reactive-firewall/multicast.git#egg=multicast" + $(QUIET)$(PYTHON) -m pip install -e "git+https://github.com/reactive-firewall/multicast.git#egg=multicast" $(QUITE)$(WAIT) $(QUIET)$(ECHO) "$@: Done." @@ -97,7 +99,9 @@ uninstall: purge: clean uninstall $(QUIET)$(PYTHON) -m pip uninstall multicast && python -m pip uninstall multicast || true + $(QUIET)$(PYTHON) ./setup.py clean || true $(QUIET)$(RMDIR) ./build/ 2>/dev/null || true + $(QUIET)$(RMDIR) ./dist/ 2>/dev/null || true $(QUIET)$(RMDIR) ./.eggs/ 2>/dev/null || true $(QUIET)$(RMDIR) ./test-reports/ 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." @@ -122,7 +126,7 @@ test-pytest: cleanup test-reports $(QUIET)$(ECHO) "$@: Done." test-style: cleanup - $(QUIET)flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || $(PYTHON) -m flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || true + $(QUIET)$(PYTHON) -m flake8 --ignore=W191,W391 --max-line-length=100 --verbose --count --config=.flake8.ini || true $(QUIET)tests/check_spelling 2>/dev/null || true $(QUIET)tests/check_cc_lines 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." diff --git a/setup.cfg b/setup.cfg index 1aeffbd5..45756cca 100644 --- a/setup.cfg +++ b/setup.cfg @@ -39,6 +39,10 @@ packages = find: [options.packages.find] +where = + multicast/ + tests/ + *.py include = multicast exclude = From 888f2ff5e460659ae8944fbc5d44b983defe77a4 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 04:30:50 -0800 Subject: [PATCH 125/135] [CONFIG] more tests for builds --- .github/workflows/Tests.yml | 41 +++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index b4e28694..06b017d9 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -13,14 +13,51 @@ jobs: python-version: 3.9 - name: Pre-Clean id: clean - run: make -j1 -f Makefile clean || true ; + run: make -j1 -f Makefile purge 2>/dev/null || true ; - name: Test Build id: build - run: make -j1 -f Makefile build || true ; + run: make -j1 -f Makefile build ; - name: Post-Clean id: post run: make -j1 -f Makefile purge || true ; + BOOTSTRAP: + if: ${{ always() }} + needs: BUILD + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.7, 3.8, 3.9] + lang-var: ["en_US.UTF-8", "de.UTF-8", "jp.UTF-8"] + env: + PYTHON_VERSION: ${{ matrix.python-version }} + LANG: ${{ matrix.lang-var }} + steps: + - uses: actions/checkout@master + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Setup dependencies + run: | + pip install -r ./requirements.txt ; + - name: Pre-build + id: bootstrap + run: | + make -j1 -f Makefile clean || true ; + make -j1 -f Makefile build ; + - name: Run Tests + id: test-install + run: make -j1 -f Makefile install || true ; + - name: Test Info + id: test-info + run: python -m setup.py --name --version --lisense || true ; + - name: Post-Clean + id: post + run: make -j1 -f Makefile clean || true ; + if: ${{ always() }} + + MATS: if: ${{ always() }} needs: BUILD From da67512ce01afb0a784ef034fc3209f8f18b9fc4 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 04:50:51 -0800 Subject: [PATCH 126/135] [REGRESSION] fixed a typo for actions ( updates #26 ) --- .github/workflows/Tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 06b017d9..6430e25c 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -40,7 +40,8 @@ jobs: python-version: ${{ matrix.python-version }} - name: Setup dependencies run: | - pip install -r ./requirements.txt ; + python -m pip install --upgrade pip setuptools wheel + pip install -r ./requirements.txt - name: Pre-build id: bootstrap run: | @@ -51,7 +52,7 @@ jobs: run: make -j1 -f Makefile install || true ; - name: Test Info id: test-info - run: python -m setup.py --name --version --lisense || true ; + run: python -m setup.py --name --version --license || true ; - name: Post-Clean id: post run: make -j1 -f Makefile clean || true ; From bf2ac9f05e8998301834ba8a2b2ce7f7b787d806 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 21:44:45 -0800 Subject: [PATCH 127/135] [STYLE] refactor blank strings to be more readable ( closes #21 ) --- .coveragerc | 3 ++- multicast/__init__.py | 44 +++++++++++++++++++++++++++++++++++-------- multicast/recv.py | 41 +++++++++++++++++++++++----------------- multicast/send.py | 10 +++++++--- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/.coveragerc b/.coveragerc index 781a31f5..e4b35673 100644 --- a/.coveragerc +++ b/.coveragerc @@ -26,7 +26,8 @@ exclude_lines = if __name__ .. .__main__.: if __sys_path__ not in sys.path: os.abort() - exit(0) + exit + partial_branches = # Have to re-enable the standard pragma rules diff --git a/multicast/__init__.py b/multicast/__init__.py index 4f9ae19f..1e7db051 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -20,7 +20,7 @@ __all__ = [ """__package__""", """__module__""", """__name__""", """__version__""", """__prologue__""", - """__doc__""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", + """__doc__""", """__BLANK""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", """__MCAST_DEFAULT_TTL""", """recv""", """send""", """__main__""" ] @@ -135,7 +135,6 @@ Testcase 2: multicast.__main__ should have a doctests. - >>> import multicast as _multicast >>> import multicast.__main__ as _main >>> @@ -149,7 +148,7 @@ """ -global __MCAST_DEFAULT_PORT +global __MCAST_DEFAULT_PORT # noqa __MCAST_DEFAULT_PORT = 19991 """ @@ -171,10 +170,13 @@ >>> type(multicast.__MCAST_DEFAULT_PORT) is type(1) True >>> + >>> multicast.__MCAST_DEFAULT_PORT > int(1024) + True + >>> """ -global __MCAST_DEFAULT_GROUP +global __MCAST_DEFAULT_GROUP # noqa __MCAST_DEFAULT_GROUP = """224.0.0.1""" """ @@ -200,7 +202,7 @@ """ -global __MCAST_DEFAULT_TTL +global __MCAST_DEFAULT_TTL # noqa """ Arbitrary TTL time to live to use by default, though any small (2-126) TTL would work. @@ -224,6 +226,32 @@ """ +global __BLANK # noqa + +__BLANK = str("""""") +""" + Arbitrary blank string. + + Minimal Testing: + + First setup test fixtures by importing multicast. + + >>> import multicast + >>> __BLANK = multicast.__BLANK + + Testcase 0: Multicast should have a default port. + A: Test that the __BLANK attribute is initialized. + B: Test that the __BLANK attribute is an empty string. + + >>> __BLANK is not None + True + >>> type(__BLANK) is type(str) + True + >>> + +""" + + try: import sys if sys.__name__ is None: @@ -253,9 +281,9 @@ if socket.__name__ is None: raise ImportError("FAIL: we could not import socket. ABORT.") if sys.platform.startswith("darwin") or sys.platform.startswith("linux"): # pragma: no-branch - __MCAST_DEFAULT_TTL = int(socket.IP_DEFAULT_MULTICAST_TTL) - else: - __MCAST_DEFAULT_TTL = int(20) + __MCAST_DEFAULT_TTL = int(socket.IP_DEFAULT_MULTICAST_TTL) # pragma: no cover + else: # pragma: no-branch + __MCAST_DEFAULT_TTL = int(20) # pragma: no cover except Exception as err: raise ImportError(err) diff --git a/multicast/recv.py b/multicast/recv.py index d9bc5462..90ac3fed 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -89,6 +89,7 @@ from . import multicast as multicast else: # pragma: no branch multicast = sys.modules["""multicast"""] + __BLANK = multicast.__BLANK except Exception as importErr: del importErr import multicast as multicast @@ -201,8 +202,8 @@ def endSocket(sock=None): if not (sock is None): # pragma: no branch try: sock.close() - sock.shutdown(socket.SHUT_RD) - except OSError: + sock.shutdown(socket.SHUT_RD) # pragma: no cover + except OSError: # pragma: no branch sock = None @@ -246,15 +247,15 @@ def parseArgs(arguments=None): description=__prologue__, epilog=__epilogue__ ) - parser.add_argument('--port', type=int, default=multicast.__MCAST_DEFAULT_PORT) + parser.add_argument("""--port""", type=int, default=multicast.__MCAST_DEFAULT_PORT) parser.add_argument( - '--join-mcast-groups', default=[], nargs='*', + """--join-mcast-groups""", default=[], nargs='*', help="""multicast groups (ip addrs) to listen to join.""" ) __tmp_help = """local interface to use for listening to multicast data; """ __tmp_help += """if unspecified, any one interface may be chosen.""" parser.add_argument( - '--iface', default=None, + """--iface""", default=None, help=str(__tmp_help) ) __tmp_help = """multicast groups (ip addrs) to bind to for the udp socket; """ @@ -264,7 +265,7 @@ def parseArgs(arguments=None): __tmp_help += """If unspecified, bind to 0.0.0.0 """ __tmp_help += """(all addresses (all multicast addresses) of that interface)""" parser.add_argument( - '--bind-group', default=None, + """--bind-group""", default=None, help=str(__tmp_help) ) return parser.parse_args(arguments) @@ -297,16 +298,13 @@ def hearstep(groups, port, iface=None, bind_group=None): >>> type(multicast.recv.hearstep) >>> multicast.recv.hearstep(None, 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS - '...' >>> tst_fxtr = multicast.__MCAST_DEFAULT_GROUP >>> multicast.recv.hearstep([tst_fxtr], 19991) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS - '...' >>> multicast.recv.hearstep( ... [tst_fxtr], 19991, None, tst_fxtr ... ) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS - '...' >>> @@ -315,7 +313,7 @@ def hearstep(groups, port, iface=None, bind_group=None): if groups is None: groups = [] sock = genSocket() - msgbuffer = str("""""") + msgbuffer = str(__BLANK) try: sock.bind(('' if bind_group is None else bind_group, port)) for group in groups: @@ -328,16 +326,18 @@ def hearstep(groups, port, iface=None, bind_group=None): chunk = None while True: chunk = sock.recv(1316) - if chunk is not None: + if not (chunk is None): msgbuffer += str(chunk, encoding='utf8') chunk = None # msgbuffer += unicodedata.lookup("""SOFT HYPHEN""") # about 969 bytes in base64 encoded as chars except KeyboardInterrupt: # pragma: no branch - print("""""") - print(str("""User Interrupted""")) + if (sys.stdout.isatty()): # pragma: no cover + print(__BLANK) + print(str("""User Interrupted""")) except OSError: # pragma: no branch - print(str("""""")) + if (sys.stdout.isatty()): # pragma: no cover + print(__BLANK) finally: sock = endSocket(sock) return msgbuffer @@ -392,8 +392,12 @@ def main(*argv): <...int...> >>> int(test_fixture) >= int(0) True + >>> type(test_fixture) is type(0) + True >>> int(test_fixture) < int(4) True + >>> (int(test_fixture) >= int(0)) and (int(test_fixture) < int(4)) + True >>> @@ -403,11 +407,14 @@ def main(*argv): args = parseArgs(*argv) hearstep(args.join_mcast_groups, int(args.port), args.iface, args.bind_group) __exit_code = 0 - except argparse.ArgumentError: - print('Input has an Argument Error') + except argparse.ArgumentError: # pragma: no branch + if (sys.stdout.isatty()): # pragma: no cover + print(__BLANK) + print(str("""Input has an Argument Error""")) __exit_code = 2 except Exception as e: - print(str(e)) + if (sys.stdout.isatty()): # pragma: no cover + print(str(e)) __exit_code = 3 return int(__exit_code) diff --git a/multicast/send.py b/multicast/send.py index f39d7ec8..de1ab7a8 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -161,6 +161,7 @@ from . import multicast as multicast else: # pragma: no branch multicast = sys.modules["""multicast"""] + __BLANK = multicast.__BLANK except Exception as importErr: del importErr import multicast as multicast @@ -287,7 +288,7 @@ def main(*argv): try: args = parseArgs(*argv) _payload = str( - unicodedata.lookup("""SOFT HYPHEN""") + unicodedata.lookup("""SOFT HYPHEN""") if sys.stdout.isatty() is True else __BLANK ).join(list(args.message)).format( name=str(__name__), group=str(args.mcast_group), @@ -296,10 +297,13 @@ def main(*argv): saystep(args.mcast_group, int(args.port), _payload) __exit_code = 0 except argparse.ArgumentError: # pragma: no branch - print('Input has an Argument Error') + if (sys.stdout.isatty()): # pragma: no cover + print(__BLANK) + print(str("""Input has an Argument Error""")) __exit_code = 2 except Exception as e: # pragma: no branch - print(str(e)) + if (sys.stdout.isatty()): # pragma: no cover + print(str(e)) __exit_code = 3 del e return int(__exit_code) From 4ec2e21d331b817fca395cb09588a448495b1eb7 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 21:55:37 -0800 Subject: [PATCH 128/135] [CONFIG] Droping Travis-CI support due to paywall. ( closes #22 ) --- .travis.yml | 278 ---------------------------------------------------- 1 file changed, 278 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0835f615..00000000 --- a/.travis.yml +++ /dev/null @@ -1,278 +0,0 @@ -language: python - -python: - -dist: - -addons: - coverity_scan: - # GitHub project metadata - project: - name: reactive-firewall/multicast - version: 1.1.3 - description: Python Multicast Repo - # Commands to prepare for build_command - # ** likely specific to your build ** - build_command_prepend: make clean - # The command that will be added as an argument to "cov-build" to compile your project for analysis, - # ** likely specific to your build ** - build_command: make test - # Pattern to match selecting branches that will run analysis. We recommend leaving this set to 'coverity_scan'. - # Take care in resource usage, and consider the build frequency allowances per - # https://scan.coverity.com/faq#frequency - branch_pattern: master - -branches: - only: - - stable - - master - -env: - -matrix: - include: - - os: linux - python: "2.7" - env: TRAVIS_PYTHON_VERSION="2.7" - dist: trusty - - os: linux - python: "3.2" - env: TRAVIS_PYTHON_VERSION="3.2" - dist: trusty - - os: linux - python: "3.3" - env: TRAVIS_PYTHON_VERSION="3.3" - dist: trusty - - os: linux - python: "3.4" - dist: xenial - env: TRAVIS_PYTHON_VERSION="3.4" - - os: linux - python: "3.5" - env: TRAVIS_PYTHON_VERSION="3.5" - dist: trusty - - os: linux - python: "3.5" - env: TRAVIS_PYTHON_VERSION="3.5" - dist: xenial - - os: linux - python: "3.6" - env: TRAVIS_PYTHON_VERSION="3.6" - - os: linux - python: "3.5-dev" # 3.5 development branch - env: TRAVIS_PYTHON_VERSION="3.5" - dist: xenial - - os: linux - python: "3.6-dev" - env: TRAVIS_PYTHON_VERSION="3.6" - dist: bionic - - os: linux - python: "3.7-dev" - env: TRAVIS_PYTHON_VERSION="3.7" - dist: bionic - - os: linux - python: "3.7" - env: TRAVIS_PYTHON_VERSION="3.7" - dist: bionic - - os: linux - python: "3.8-dev" - env: TRAVIS_PYTHON_VERSION="3.8" - dist: bionic - - os: linux - python: "3.9-dev" - env: TRAVIS_PYTHON_VERSION="3.9" - dist: bionic - - os: linux - python: "pypy2.7-5.8.0" - dist: xenial - - os: linux - python: "pypy3.5-5.8.0" - dist: xenial - - os: linux - python: "pypy3.5-6.0" - dist: xenial - - os: linux - python: "pypy3.5-5.10.0" - env: TRAVIS_PYTHON_VERSION="3.5" - dist: xenial - - os: linux - python: "pypy2.7-5.10.0" - env: TRAVIS_PYTHON_VERSION="2.7" - dist: xenial - - os: linux - python: "nightly" # currently points to 3.9-dev - env: TRAVIS_PYTHON_VERSION="3.9-dev" - - os: osx - osx_image: xcode10 - language: shell - - os: osx - osx_image: xcode11.1 - language: shell - - os: osx - osx_image: xcode11.2 - language: shell - - os: osx - osx_image: xcode11.3 - language: shell - allow_failures: - - os: linux - dist: xenial - - os: linux - dist: trusty - - os: linux - python: "3.9-dev" - - os: linux - python: "2.6" - - os: linux - python: "3.2" - - os: linux - python: "3.3" - - os: linux - python: "3.4" - dist: xenial - - os: linux - python: "3.4" - dist: bionic - - os: linux - python: "3.7-dev" - - os: linux - python: "3.8-dev" - - os: linux - python: "3.9-dev" - - os: linux - python: "nightly" - - os: linux - python: "pypy" - - os: linux - python: "pypy3" - - os: linux - python: "pypy3.5-5.8.0" - - os: linux - python: "pypy2.7-5.8.0" - - os: linux - python: "pypy3.5-5.10.0" - - os: linux - python: "pypy2.7-5.10.0" - - os: linux - python: "pypy3.5-6.0" - - os: osx - osx_image: xcode6.4 - language: shell - - os: osx - osx_image: xcode7.2 - language: shell - - os: osx - osx_image: xcode7.3 - language: shell - - os: osx - osx_image: xcode8 - language: shell - - os: osx - osx_image: xcode8.3 - language: shell - - os: osx - osx_image: xcode9 - language: shell - - os: osx - osx_image: xcode9.2 - language: shell - - os: osx - osx_image: xcode9.3 - language: shell - - os: osx - osx_image: xcode9.4 - language: shell - - os: osx - osx_image: xcode10 - language: shell - - os: osx - osx_image: xcode10.1 - language: shell - - os: osx - osx_image: xcode11 - language: shell - - os: osx - osx_image: xcode11.1 - language: shell - - -install: "make init" - -before_install: - - if [ $TRAVIS_OS_NAME == osx ] ; then travis_wait git -C "$(brew --repo homebrew/core)" fetch --unshallow || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then travis_retry brew tap homebrew/versions || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then travis_wait brew upgrade || travis_retry brew upgrade || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python2.6 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python26 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then travis_wait brew install python3 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python3.3 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install py3.3 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python3.4 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python34 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install py3.4 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python3.5 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python35 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install py3.5 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python3.6 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python36 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install py3.6 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python2.7 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python27 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install py2.7 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python3.6 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install python3.7 || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install coverage $INSTALL || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install codecov || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then brew install pip || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then export VERSIONER_PYTHON_VERSION=${TRAVIS_PYTHON_VERSION:-3.7} || true ; fi - - if [ $TRAVIS_OS_NAME == osx ] ; then defaults write com.apple.versioner.python Version $TRAVIS_PYTHON_VERSION || true ; fi - - travis_retry pip install tox || pip install tox || true ; - - travis_retry pip install coverage || true ; - - travis_retry pip install codecov || true ; - - travis_retry python -m pip install coverage || python -m pip install coverage || true ; - - travis_retry python -m pip install codecov || python -m pip install codecov || true ; - - travis_retry python3 -m pip3 install tox || python3 -m pip install tox || true ; - - travis_retry python3 -m pip3 install coverage || python3 -m pip install coverage || true ; - - travis_retry python3 -m pip3 install codecov || python3 -m pip install codecov || true ; - - travis_retry python3 -m pip3 install -r requirements.txt || python3 -m pip install -r requirements.txt || true ; - -# The following is used to get coveralls working: add affter codecov -# - travis_retry pip install python-coveralls 2>/dev/null || python3 -m pip install python-coveralls || true ; -# - coveralls 2>/dev/null || true -# - travis_retry pip uninstall -y python-coveralls || travis_retry python3 -m pip uninstall -y python-coveralls || true -# - travis_retry pip uninstall -y PyYAML || travis_retry python3 -m pip uninstall -y PyYAML || true - -before_script: - - if [ $TRAVIS_OS_NAME == osx ] ; then echo "SKIP code climate" ; else curl -L --url https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 -o ./cc-test-reporter 3>/dev/null 2>/dev/null || true ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] ; then echo "SKIP code climate" ; else chmod +x ./cc-test-reporter || true ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] ; then echo "SKIP code climate" ; else ./cc-test-reporter before-build || true ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] ; then echo "SKIP deepsource" ; else (curl https://deepsource.io/cli | sh) || true ; fi ; - -script: - - make clean ; - - if [ $TRAVIS_OS_NAME == osx ] ; then echo "SKIP make test" ; else make test || exit $? ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] || [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP codecov" ; else codecov || exit $? ; fi ; - - cp -vf .coverage ".coverall.Lasting.45678.12345" 2>/dev/null || true - - make clean || exit $? ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] || [ $TRAVIS_PYTHON_VERSION == "3.3" ] ; then echo "SKIP make test-tox" ; else make test-tox || exit $? ; fi ; - - make clean || true ; - - mv -vf ".coverall.Lasting.45678.12345" .coverage 2>/dev/null || true - -after_failure: - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP coverage" ; else coverage combine 2>/dev/null || true ; fi ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP coverage xml" ; else coverage xml 2>/dev/null || true ; fi ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP codecov" ; else codecov 2>/dev/null || true ; fi ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] || [ $TRAVIS_PYTHON_VERSION == "3.2" ] || [ $TRAVIS_PYTHON_VERSION == "3.3" ] ; then echo "SKIP code climate" ; else ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT || true ; fi ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] || [ $TRAVIS_PYTHON_VERSION == "3.3" ] ; then echo "SKIP codecov" ; else codecov 2>/dev/null || true ; fi ; - - make clean 2>/dev/null || true - -after_success: - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP coverage" ; else coverage combine 2>/dev/null || true ; fi ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP coverage xml" ; else coverage xml 2>/dev/null || true ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] || [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP code climate" ; else ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT || true ; fi ; - - if [ $TRAVIS_OS_NAME == osx ] || [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP deepsource" ; else ./bin/deepsource report --analyzer test-coverage --key python --value-file ./coverage.xml 2>/dev/null || true ; fi ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP codecov" ; else codecov || true ; fi ; - - travis_retry python3 -m pip install python-coveralls || python3 -m pip install python-coveralls || true ; - - if [ $TRAVIS_PYTHON_VERSION == "3.2" ] ; then echo "SKIP codecov" ; else coveralls 2>/dev/null || true ; fi ; - From fe25e79071dcfdab34e3d51653e72003591d15a7 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 21:57:03 -0800 Subject: [PATCH 129/135] [CONFIG] drop Travis-CI ( closes #22 ) --- .yamllint.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.yamllint.conf b/.yamllint.conf index c4724781..6d6934bd 100644 --- a/.yamllint.conf +++ b/.yamllint.conf @@ -3,7 +3,7 @@ extends: default rules: line-length: - max: 280 + max: 100 level: warning indentation: indent-sequences: whatever \ No newline at end of file From 6e51ea0902deeea14bb5dcb852d0f9fd152637c6 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 22:21:37 -0800 Subject: [PATCH 130/135] [DOCUMENTATION] Clearified a docStrings a little. ( updates #33 ) --- multicast/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multicast/__main__.py b/multicast/__main__.py index fdd601fd..5b4d9322 100644 --- a/multicast/__main__.py +++ b/multicast/__main__.py @@ -174,7 +174,7 @@ def SendMCast(*args, **kwargs): def joinMCast(*args, **kwargs): - """Will listen for multicast messages.""" + """Will subscribe and listen for multicast messages to a given group.""" return recv.main(*args, **kwargs) From 53e8a8f7e522a24d44416c98f4013268a92bee38 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 22:44:25 -0800 Subject: [PATCH 131/135] [FEATURE] add user-install option. ( updates #26 ) --- Makefile | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1b98a71e..86be3501 100644 --- a/Makefile +++ b/Makefile @@ -77,32 +77,33 @@ endif PHONY: must_be_root cleanup build: - $(QUIET)$(ECHO) "INFO: No need to build. Try make -f Makefile install" + $(QUIET)$(ECHO) "INFO: No need to build. Try 'make -f Makefile install'" $(QUIET)$(PYTHON) setup.py build $(QUIET)$(PYTHON) setup.py bdist_wheel --universal $(QUITE)$(WAIT) $(QUIET)$(ECHO) "build DONE." init: + $(QUIET)$(PYTHON) -m pip install --upgrade pip setuptools wheel 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." -install: build must_be_root - $(QUIET)$(PYTHON) -m pip install --upgrade pip setuptools wheel || true +install: init build must_be_root $(QUIET)$(PYTHON) -m pip install -e "git+https://github.com/reactive-firewall/multicast.git#egg=multicast" $(QUITE)$(WAIT) $(QUIET)$(ECHO) "$@: Done." uninstall: - $(QUITE)$(PYTHON) -m pip uninstall multicast || true + $(QUIET)$(PYTHON) -m pip uninstall multicast && python -m pip uninstall multicast 2>/dev/null || true $(QUITE)$(WAIT) $(QUIET)$(ECHO) "$@: Done." purge: clean uninstall - $(QUIET)$(PYTHON) -m pip uninstall multicast && python -m pip uninstall multicast || true + $(QUIET)$(PYTHON) ./setup.py uninstall 2>/dev/null || true $(QUIET)$(PYTHON) ./setup.py clean || true $(QUIET)$(RMDIR) ./build/ 2>/dev/null || true $(QUIET)$(RMDIR) ./dist/ 2>/dev/null || true $(QUIET)$(RMDIR) ./.eggs/ 2>/dev/null || true + $(QUIET)$(RM) ./test-results/junit.xml 2>/dev/null || true $(QUIET)$(RMDIR) ./test-reports/ 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." @@ -158,6 +159,9 @@ cleanup: $(QUIET)$(RM) ./.*/*~ 2>/dev/null || true $(QUIET)$(RM) ./*~ 2>/dev/null || true $(QUIET)$(RM) ./.*~ 2>/dev/null || true + $(QUIET)$(RM) ./src/**/* 2>/dev/null || true + $(QUIET)$(RM) ./src/* 2>/dev/null || true + $(QUIET)$(RMDIR) ./src/ 2>/dev/null || true $(QUIET)$(RMDIR) tests/__pycache__ 2>/dev/null || true $(QUIET)$(RMDIR) multicast/__pycache__ 2>/dev/null || true $(QUIET)$(RMDIR) multicast/*/__pycache__ 2>/dev/null || true @@ -172,8 +176,6 @@ cleanup: clean: cleanup $(QUIET)$(COVERAGE) erase 2>/dev/null || true $(QUIET)$(RM) ./test-results/junit.xml 2>/dev/null || true - $(QUIET)$(RMDIR) ./test-results/ 2>/dev/null || true - $(QUIET)$(RMDIR) ./build/ 2>/dev/null || true $(QUIET)$(MAKE) -s -C ./docs/ -f Makefile clean 2>/dev/null || true $(QUIET)$(ECHO) "$@: Done." @@ -181,6 +183,14 @@ must_be_root: $(QUIET)runner=`whoami` ; \ if test $$runner != "root" ; then $(ECHO) "You are not root." ; exit 1 ; fi +user-install: build + $(QUIET)$(PYTHON) -m pip install --user --upgrade pip setuptools wheel || true + $(QUIET)$(PYTHON) -m pip install --user -r "https://github.com/raw/reactive-firewall/multicast/master/requirements.txt" + $(QUIET)$(PYTHON) -m pip install --user -e "git+https://github.com/reactive-firewall/multicast.git#egg=multicast" + $(QUITE)$(WAIT) + $(QUIET)$(ECHO) "$@: Done." + + %: $(QUIET)$(ECHO) "No Rule Found For $@" ; $(WAIT) ; From 63055a4294dfda0e016e7629e74db575439b3838 Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Sun, 6 Mar 2022 22:59:42 -0800 Subject: [PATCH 132/135] [FEATURE] add tests for user-install option. ( updates #26 ) --- .github/workflows/Tests.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 6430e25c..d04dc62a 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -49,13 +49,15 @@ jobs: make -j1 -f Makefile build ; - name: Run Tests id: test-install - run: make -j1 -f Makefile install || true ; + run: make -j1 -f Makefile user-install ; - name: Test Info id: test-info run: python -m setup.py --name --version --license || true ; - name: Post-Clean id: post - run: make -j1 -f Makefile clean || true ; + run: | + make -j1 -f Makefile purge || true ; + make -j1 -f Makefile clean || true ; if: ${{ always() }} @@ -145,6 +147,12 @@ jobs: name: multicast-github-${{ matrix.os }}-${{ matrix.python-version }} verbose: true fail_ci_if_error: true + - name: Upload Python ${{ matrix.python-version }} Artifact + uses: actions/upload-artifact@v3 + with: + name: Test-Report-${{ matrix.os }}-${{ matrix.python-version }} + path: ./test-reports/ + if-no-files-found: ignore - name: code-climate for ${{ matrix.python-version }} if: ${{ runner.os }} == "Linux" shell: bash From f025b4823b8e909a4723ea9524c17ae1f124586a Mon Sep 17 00:00:00 2001 From: "Mr. Walls" Date: Sun, 6 Mar 2022 23:24:26 -0800 Subject: [PATCH 133/135] [REGRESSION] fix typo in multicast/recv.py --- multicast/recv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multicast/recv.py b/multicast/recv.py index 90ac3fed..8e986c01 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -202,7 +202,7 @@ def endSocket(sock=None): if not (sock is None): # pragma: no branch try: sock.close() - sock.shutdown(socket.SHUT_RD) # pragma: no cover + sock.shutdown(socket.SHUT_RD) # pragma: no cover except OSError: # pragma: no branch sock = None From 8f3bdee7b6f18fc59f805a58c634b1478fc81a7d Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 7 Mar 2022 01:40:45 -0800 Subject: [PATCH 134/135] [STAGE] Partial Refactor for main entry point. ( unstable ) --- multicast/{__main__.py => runner.py} | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) rename multicast/{__main__.py => runner.py} (98%) diff --git a/multicast/__main__.py b/multicast/runner.py similarity index 98% rename from multicast/__main__.py rename to multicast/runner.py index 5b4d9322..92d36c25 100644 --- a/multicast/__main__.py +++ b/multicast/runner.py @@ -362,13 +362,12 @@ def main(*argv): except BaseException: # pragma: no branch e = str("CRITICAL - An error occured while handling") e += str(" the cascading failure.") - if (sys.stdout.isatty()): # pragma: no cover - print(str(e)) + print(str(e)) __EXIT_CODE = 3 return __EXIT_CODE # noqa -if __name__ in '__main__': +if __name__ in """__main__""": __EXIT_CODE = 2 if (sys.argv is not None) and (len(sys.argv) > 1): __EXIT_CODE = main(sys.argv[1:]) From a68e5ef2f8d1c555b82aaa78dc7d54dc30fd9cea Mon Sep 17 00:00:00 2001 From: reactive-firewall Date: Mon, 7 Mar 2022 02:59:20 -0800 Subject: [PATCH 135/135] [REGRESSION] fix for CLI bug --- multicast/__init__.py | 16 ++++++++-------- multicast/{runner.py => __main__.py} | 19 ++++++++++--------- multicast/recv.py | 7 ++++++- multicast/send.py | 4 +--- tests/context.py | 9 +++++---- tests/test_usage.py | 23 +++++++++++++++++------ 6 files changed, 47 insertions(+), 31 deletions(-) rename multicast/{runner.py => __main__.py} (95%) diff --git a/multicast/__init__.py b/multicast/__init__.py index 1e7db051..93e555f2 100644 --- a/multicast/__init__.py +++ b/multicast/__init__.py @@ -21,7 +21,7 @@ __all__ = [ """__package__""", """__module__""", """__name__""", """__version__""", """__prologue__""", """__doc__""", """__BLANK""", """__MCAST_DEFAULT_PORT""", """__MCAST_DEFAULT_GROUP""", - """__MCAST_DEFAULT_TTL""", """recv""", """send""", """__main__""" + """__MCAST_DEFAULT_TTL""", """recv""", """send""" ] __package__ = """multicast""" @@ -248,6 +248,9 @@ >>> type(__BLANK) is type(str) True >>> + >>> len(__BLANK) <= 0 + True + >>> """ @@ -317,17 +320,14 @@ try: - if 'multicast.__main__' not in sys.modules: - from . import __main__ as __main__ - else: # pragma: no branch + if """multicast.__main__""" in sys.modules: # pragma: no cover __main__ = sys.modules["""multicast.__main__"""] except Exception: import multicast.__main__ as __main__ -if __name__ == '__main__': +if __name__ in u'__main__': __EXIT_CODE = 2 - if __main__.__name__ is None: - raise ImportError(str("Failed to open multicast")) - __EXIT_CODE = __main__.main(sys.argv[1:]) + if __main__.main is not None: + __EXIT_CODE = __main__.main(sys.argv[1:]) exit(__EXIT_CODE) diff --git a/multicast/runner.py b/multicast/__main__.py similarity index 95% rename from multicast/runner.py rename to multicast/__main__.py index 92d36c25..56dc8c7e 100644 --- a/multicast/runner.py +++ b/multicast/__main__.py @@ -31,7 +31,7 @@ __package__ = """multicast""" -__module__ = """multicast""" +__module__ = """multicast.__main__""" __file__ = """multicast/__main__.py""" @@ -106,13 +106,13 @@ try: - if 'multicast' not in sys.modules: - from . import multicast as multicast + if 'multicast.__version__' not in sys.modules: + from . import __version__ as __version__ else: # pragma: no branch - multicast = sys.modules["""multicast"""] + __version__ = sys.modules["""multicast.__version__"""] except Exception as importErr: del importErr - import multicast as multicast + import multicast.__version__ as __version__ try: @@ -174,7 +174,7 @@ def SendMCast(*args, **kwargs): def joinMCast(*args, **kwargs): - """Will subscribe and listen for multicast messages to a given group.""" + """Will listen for multicast messages.""" return recv.main(*args, **kwargs) @@ -238,7 +238,7 @@ def buildArgs(): '-V', '--version', action='version', version=str( "%(prog)s {version}" - ).format(version=str(multicast.__version__)) + ).format(version=str(__version__)) ) parser.add_argument( 'some_task', nargs='?', choices=TASK_OPTIONS.keys(), @@ -362,12 +362,13 @@ def main(*argv): except BaseException: # pragma: no branch e = str("CRITICAL - An error occured while handling") e += str(" the cascading failure.") - print(str(e)) + if (sys.stdout.isatty()): # pragma: no cover + print(str(e)) __EXIT_CODE = 3 return __EXIT_CODE # noqa -if __name__ in """__main__""": +if __name__ in '__main__': __EXIT_CODE = 2 if (sys.argv is not None) and (len(sys.argv) > 1): __EXIT_CODE = main(sys.argv[1:]) diff --git a/multicast/recv.py b/multicast/recv.py index 8e986c01..906ddbf1 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -405,7 +405,12 @@ def main(*argv): __exit_code = 1 try: args = parseArgs(*argv) - hearstep(args.join_mcast_groups, int(args.port), args.iface, args.bind_group) + response = hearstep(args.join_mcast_groups, int(args.port), args.iface, args.bind_group) + if (sys.stdout.isatty() and len(response) > 0): # pragma: no cover + print(__BLANK) + print(str(response)) + print(__BLANK) + del response __exit_code = 0 except argparse.ArgumentError: # pragma: no branch if (sys.stdout.isatty()): # pragma: no cover diff --git a/multicast/send.py b/multicast/send.py index de1ab7a8..0863848e 100644 --- a/multicast/send.py +++ b/multicast/send.py @@ -287,9 +287,7 @@ def main(*argv): __exit_code = 1 try: args = parseArgs(*argv) - _payload = str( - unicodedata.lookup("""SOFT HYPHEN""") if sys.stdout.isatty() is True else __BLANK - ).join(list(args.message)).format( + _payload = str(args.message).format( name=str(__name__), group=str(args.mcast_group), port=int(args.port) diff --git a/tests/context.py b/tests/context.py index b0d84f7a..0d70c393 100644 --- a/tests/context.py +++ b/tests/context.py @@ -263,8 +263,9 @@ def checkCovCommand(args=[None]): def checkStrOrByte(theInput): theOutput = None - try: + if theInput is not None: theOutput = theInput + try: if isinstance(theInput, bytes): theOutput = theInput.decode("""UTF-8""") except UnicodeDecodeError: @@ -272,11 +273,11 @@ def checkStrOrByte(theInput): return theOutput -def checkPythonCommand(args=[None], stderr=None): +def checkPythonCommand(args, stderr=None): """function for backend subprocess check_output command""" theOutput = None try: - if args is None or args is [None]: # pragma: no branch + if (args is None) or (args is [None]) or (len(args) <= 0): # pragma: no branch theOutput = subprocess.check_output(["exit 1 ; #"]) else: if str("coverage") in args[0]: @@ -381,7 +382,7 @@ def debugBlob(blob=None): print(str("""\"""")) print(__BLANK) except Exception: - return False + print(__BLANK) return True diff --git a/tests/test_usage.py b/tests/test_usage.py index f212661c..5dc6e2e0 100644 --- a/tests/test_usage.py +++ b/tests/test_usage.py @@ -311,12 +311,23 @@ def test_Usage_Error_WHEN_the_help_command_is_called(self): str("--help") ] theOutputtxt = context.checkPythonCommand(args, stderr=subprocess.STDOUT) - self.assertIn(str("usage:"), str(theOutputtxt)) - if (str("usage:") in str(theOutputtxt)): - theResult = True - else: - theResult = False - context.debugUnexpectedOutput(str("usage:"), str(theOutputtxt), self._thepython) + context.debugBlob(theOutputtxt) + # now test it + try: + if isinstance(theOutputtxt, bytes): + theOutputtxt = theOutputtxt.decode('utf8') + except UnicodeDecodeError: + theOutputtxt = str(repr(bytes(theOutputtxt))) + # or simply: + self.assertIsNotNone(theOutputtxt) + self.assertIn(str("""usage:"""), str(theOutputtxt)) + if (str("""usage:""") in str(theOutputtxt)): + theResult = True or theResult + else: + theResult = False + context.debugUnexpectedOutput( + str("usage:"), str(theOutputtxt), self._thepython + ) except Exception as err: context.debugtestError(err) err = None