summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Hennion <nicolashennion@gmail.com>2023-05-09 11:22:44 +0200
committerGitHub <noreply@github.com>2023-05-09 11:22:44 +0200
commitc7409dbc16eb2be175330eae3ffabf7366758fc2 (patch)
tree9454e200345465ace5b73219f93250ae66796d88
parent2ac6f4d4bf1af1c8506bd36f91bff04141f673da (diff)
parent0b62107f395297317f1906a2e82f5f57baa3190f (diff)
Merge pull request #2376 from nicolargo/cleanup-ci
Run CI tests on Windows with Github Actions
-rw-r--r--.ci/appveyor/README.rst2
-rw-r--r--.ci/appveyor/download_exes.py148
-rw-r--r--.ci/appveyor/install.ps185
-rw-r--r--.ci/appveyor/run_with_compiler.cmd88
-rw-r--r--.github/workflows/test.yml31
-rw-r--r--appveyor.yml107
-rw-r--r--glances/plugins/glances_network.py4
-rwxr-xr-xunitest.py10
8 files changed, 40 insertions, 435 deletions
diff --git a/.ci/appveyor/README.rst b/.ci/appveyor/README.rst
deleted file mode 100644
index 2e092a07..00000000
--- a/.ci/appveyor/README.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory contains support files for appveyor, a continuous integration
-service which runs tests on Windows on every push.
diff --git a/.ci/appveyor/download_exes.py b/.ci/appveyor/download_exes.py
deleted file mode 100644
index 2e8973c1..00000000
--- a/.ci/appveyor/download_exes.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2009 Giampaolo Rodola'. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Script which downloads exe and wheel files hosted on AppVeyor:
-https://ci.appveyor.com/project/giampaolo/psutil
-Copied and re-adapted from the original recipe of Ibarra Corretge'
-<saghul@gmail.com>:
-http://code.saghul.net/index.php/2015/09/09/
-"""
-
-from __future__ import print_function
-import argparse
-import errno
-import multiprocessing
-import os
-import requests
-import shutil
-import sys
-
-from concurrent.futures import ThreadPoolExecutor
-
-
-BASE_URL = 'https://ci.appveyor.com/api'
-PY_VERSIONS = ['2.7', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9']
-
-
-def term_supports_colors(file=sys.stdout):
- try:
- import curses
- assert file.isatty()
- curses.setupterm()
- assert curses.tigetnum("colors") > 0
- except Exception:
- return False
- else:
- return True
-
-
-if term_supports_colors():
- def hilite(s, ok=True, bold=False):
- """Return an highlighted version of 'string'."""
- attr = []
- if ok is None: # no color
- pass
- elif ok: # green
- attr.append('32')
- else: # red
- attr.append('31')
- if bold:
- attr.append('1')
- return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), s)
-else:
- def hilite(s, *a, **k):
- return s
-
-
-def safe_makedirs(path):
- try:
- os.makedirs(path)
- except OSError as err:
- if err.errno == errno.EEXIST:
- if not os.path.isdir(path):
- raise
- else:
- raise
-
-
-def safe_rmtree(path):
- def onerror(fun, path, excinfo):
- exc = excinfo[1]
- if exc.errno != errno.ENOENT:
- raise
-
- shutil.rmtree(path, onerror=onerror)
-
-
-def download_file(url):
- local_fname = url.split('/')[-1]
- local_fname = os.path.join('dist', local_fname)
- print(local_fname)
- safe_makedirs('dist')
- r = requests.get(url, stream=True)
- with open(local_fname, 'wb') as f:
- for chunk in r.iter_content(chunk_size=1024):
- if chunk: # filter out keep-alive new chunks
- f.write(chunk)
- return local_fname
-
-
-def get_file_urls(options):
- session = requests.Session()
- data = session.get(
- BASE_URL + '/projects/' + options.user + '/' + options.project)
- data = data.json()
-
- urls = []
- for job in (job['jobId'] for job in data['build']['jobs']):
- job_url = BASE_URL + '/buildjobs/' + job + '/artifacts'
- data = session.get(job_url)
- data = data.json()
- for item in data:
- file_url = job_url + '/' + item['fileName']
- urls.append(file_url)
- if not urls:
- sys.exit("no artifacts found")
- for url in sorted(urls, key=lambda x: os.path.basename(x)):
- yield url
-
-
-def rename_27_wheels():
- # See: https://github.com/giampaolo/psutil/issues/810
- src = 'dist/psutil-4.3.0-cp27-cp27m-win32.whl'
- dst = 'dist/psutil-4.3.0-cp27-none-win32.whl'
- print("rename: %s\n %s" % (src, dst))
- os.rename(src, dst)
- src = 'dist/psutil-4.3.0-cp27-cp27m-win_amd64.whl'
- dst = 'dist/psutil-4.3.0-cp27-none-win_amd64.whl'
- print("rename: %s\n %s" % (src, dst))
- os.rename(src, dst)
-
-
-def main(options):
- files = []
- safe_rmtree('dist')
- with ThreadPoolExecutor(max_workers=multiprocessing.cpu_count()) as e:
- for url in get_file_urls(options):
- fut = e.submit(download_file, url)
- files.append(fut.result())
- # 2 exes (32 and 64 bit) and 2 wheels (32 and 64 bit) for each ver.
- expected = len(PY_VERSIONS) * 4
- got = len(files)
- if expected != got:
- print(hilite("expected %s files, got %s" % (expected, got), ok=False),
- file=sys.stderr)
- rename_27_wheels()
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- description='AppVeyor artifact downloader')
- parser.add_argument('--user', required=True)
- parser.add_argument('--project', required=True)
- args = parser.parse_args()
- main(args)
diff --git a/.ci/appveyor/install.ps1 b/.ci/appveyor/install.ps1
deleted file mode 100644
index 3f056282..00000000
--- a/.ci/appveyor/install.ps1
+++ /dev/null
@@ -1,85 +0,0 @@
-# Sample script to install Python and pip under Windows
-# Authors: Olivier Grisel and Kyle Kastner
-# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-
-$BASE_URL = "https://www.python.org/ftp/python/"
-$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
-$GET_PIP_PATH = "C:\get-pip.py"
-
-
-function DownloadPython ($python_version, $platform_suffix) {
- $webclient = New-Object System.Net.WebClient
- $filename = "python-" + $python_version + $platform_suffix + ".msi"
- $url = $BASE_URL + $python_version + "/" + $filename
-
- $basedir = $pwd.Path + "\"
- $filepath = $basedir + $filename
- if (Test-Path $filename) {
- Write-Host "Reusing" $filepath
- return $filepath
- }
-
- # Download and retry up to 5 times in case of network transient errors.
- Write-Host "Downloading" $filename "from" $url
- $retry_attempts = 3
- for($i=0; $i -lt $retry_attempts; $i++){
- try {
- $webclient.DownloadFile($url, $filepath)
- break
- }
- Catch [Exception]{
- Start-Sleep 1
- }
- }
- Write-Host "File saved at" $filepath
- return $filepath
-}
-
-
-function InstallPython ($python_version, $architecture, $python_home) {
- Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
- if (Test-Path $python_home) {
- Write-Host $python_home "already exists, skipping."
- return $false
- }
- if ($architecture -eq "32") {
- $platform_suffix = ""
- } else {
- $platform_suffix = ".amd64"
- }
- $filepath = DownloadPython $python_version $platform_suffix
- Write-Host "Installing" $filepath "to" $python_home
- $args = "/qn /i $filepath TARGETDIR=$python_home"
- Write-Host "msiexec.exe" $args
- Start-Process -FilePath "msiexec.exe" -ArgumentList $args -Wait -Passthru
- Write-Host "Python $python_version ($architecture) installation complete"
- return $true
-}
-
-
-function InstallPip ($python_home) {
- $pip_path = $python_home + "/Scripts/pip.exe"
- $python_path = $python_home + "/python.exe"
- if (-not(Test-Path $pip_path)) {
- Write-Host "Installing pip..."
- $webclient = New-Object System.Net.WebClient
- $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
- Write-Host "Executing:" $python_path $GET_PIP_PATH
- Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru
- } else {
- Write-Host "pip already installed."
- }
-}
-
-function InstallPackage ($python_home, $pkg) {
- $pip_path = $python_home + "/Scripts/pip.exe"
- & $pip_path install $pkg
-}
-
-function main () {
- InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
- InstallPip $env:PYTHON
- InstallPackage $env:PYTHON wheel
-}
-
-main
diff --git a/.ci/appveyor/run_with_compiler.cmd b/.ci/appveyor/run_with_compiler.cmd
deleted file mode 100644
index 5da547c4..00000000
--- a/.ci/appveyor/run_with_compiler.cmd
+++ /dev/null
@@ -1,88 +0,0 @@
-:: To build extensions for 64 bit Python 3, we need to configure environment
-:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
-:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
-::
-:: To build extensions for 64 bit Python 2, we need to configure environment
-:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
-:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
-::
-:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
-:: environment configurations.
-::
-:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
-:: cmd interpreter, at least for (SDK v7.0)
-::
-:: More details at:
-:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
-:: http://stackoverflow.com/a/13751649/163740
-::
-:: Author: Olivier Grisel
-:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-::
-:: Notes about batch files for Python people:
-::
-:: Quotes in values are literally part of the values:
-:: SET FOO="bar"
-:: FOO is now five characters long: " b a r "
-:: If you don't want quotes, don't include them on the right-hand side.
-::
-:: The CALL lines at the end of this file look redundant, but if you move them
-:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
-:: case, I don't know why.
-@ECHO OFF
-
-SET COMMAND_TO_RUN=%*
-SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
-SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
-
-:: Extract the major and minor versions, and allow for the minor version to be
-:: more than 9. This requires the version number to have two dots in it.
-SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
-IF "%PYTHON_VERSION:~3,1%" == "." (
- SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
-) ELSE (
- SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
-)
-
-:: Based on the Python version, determine what SDK version to use, and whether
-:: to set the SDK for 64-bit.
-IF %MAJOR_PYTHON_VERSION% == 2 (
- SET WINDOWS_SDK_VERSION="v7.0"
- SET SET_SDK_64=Y
-) ELSE (
- IF %MAJOR_PYTHON_VERSION% == 3 (
- SET WINDOWS_SDK_VERSION="v7.1"
- IF %MINOR_PYTHON_VERSION% LEQ 4 (
- SET SET_SDK_64=Y
- ) ELSE (
- SET SET_SDK_64=N
- IF EXIST "%WIN_WDK%" (
- :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
- REN "%WIN_WDK%" 0wdf
- )
- )
- ) ELSE (
- ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
- EXIT 1
- )
-)
-
-IF %PYTHON_ARCH% == 64 (
- IF %SET_SDK_64% == Y (
- ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
- SET DISTUTILS_USE_SDK=1
- SET MSSdk=1
- "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
- "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
- ECHO Executing: %COMMAND_TO_RUN%
- call %COMMAND_TO_RUN% || EXIT 1
- ) ELSE (
- ECHO Using default MSVC build environment for 64 bit architecture
- ECHO Executing: %COMMAND_TO_RUN%
- call %COMMAND_TO_RUN% || EXIT 1
- )
-) ELSE (
- ECHO Using default MSVC build environment for 32 bit architecture
- ECHO Executing: %COMMAND_TO_RUN%
- call %COMMAND_TO_RUN% || EXIT 1
-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4109588c..e11d4d1f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -5,7 +5,7 @@ name: test
on: [push]
jobs:
- test:
+ test-linux:
runs-on: ubuntu-latest
strategy:
@@ -56,4 +56,31 @@ jobs:
uses: jpetrucciani/bandit-check@master
with:
#path: '-r --exit-zero --skip B104 ./glances/'
- path: '-r --exit-zero --skip B104 ./glances/' \ No newline at end of file
+ path: '-r --exit-zero --skip B104 ./glances/'
+
+
+ test-windows:
+
+ runs-on: windows-latest
+ strategy:
+ matrix:
+ python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
+
+ steps:
+
+ - uses: actions/checkout@v3
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ if (Test-Path -PathType Leaf "requirements.txt") { python -m pip install -r requirements.txt }
+ python setup.py install
+
+ - name: Unitary tests
+ run: |
+ python ./unitest.py
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 5b8be86a..00000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,107 +0,0 @@
-os: Visual Studio 2015
-
-environment:
-
- matrix:
- # Pre-installed Python versions, which Appveyor may upgrade to
- # a later point release.
-
- # 32 bits
-
- - PYTHON: "C:\\Python27"
- PYTHON_VERSION: "2.7.x"
- PYTHON_ARCH: "32"
-
- - PYTHON: "C:\\Python35"
- PYTHON_VERSION: "3.5.x"
- PYTHON_ARCH: "32"
-
- - PYTHON: "C:\\Python36"
- PYTHON_VERSION: "3.6.x"
- PYTHON_ARCH: "32"
-
- - PYTHON: "C:\\Python37"
- PYTHON_VERSION: "3.7.x"
- PYTHON_ARCH: "32"
-
- - PYTHON: "C:\\Python38"
- PYTHON_VERSION: "3.8.x"
- PYTHON_ARCH: "32"
-
- - PYTHON: "C:\\Python39"
- PYTHON_VERSION: "3.9.x"
- PYTHON_ARCH: "32"
-
- # 64 bits
-
- - PYTHON: "C:\\Python27-x64"
- PYTHON_VERSION: "2.7.x"
- PYTHON_ARCH: "64"
-
- - PYTHON: "C:\\Python35-x64"
- PYTHON_VERSION: "3.5.x"
- PYTHON_ARCH: "64"
- ARCH: x86_64
- VS_VER: "2015"
- INSTANCENAME: "SQL2012SP1"
-
- - PYTHON: "C:\\Python36-x64"
- PYTHON_VERSION: "3.6.x"
- PYTHON_ARCH: "64"
- ARCH: x86_64
- VS_VER: "2015"
- INSTANCENAME: "SQL2012SP1"
-
- - PYTHON: "C:\\Python37-x64"
- PYTHON_VERSION: "3.7.x"
- PYTHON_ARCH: "64"
- ARCH: x86_64
- VS_VER: "2015"
- INSTANCENAME: "SQL2012SP1"
-
- - PYTHON: "C:\\Python38-x64"
- PYTHON_VERSION: "3.8.x"
- PYTHON_ARCH: "64"
- ARCH: x86_64
- VS_VER: "2015"
- INSTANCENAME: "SQL2012SP1"
-
- - PYTHON: "C:\\Python39-x64"
- PYTHON_VERSION: "3.9.x"
- PYTHON_ARCH: "64"
- ARCH: x86_64
- VS_VER: "2015"
- INSTANCENAME: "SQL2012SP1"
-
- # Also build on a Python version not pre-installed by Appveyor.
- # See: https://github.com/ogrisel/python-appveyor-demo/issues/10
-
- # - PYTHON: "C:\\Python266"
- # PYTHON_VERSION: "2.6.6"
- # PYTHON_ARCH: "32"
-
-init:
- - "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%"
-
-install:
- - "powershell .ci\\appveyor\\install.ps1"
- # - ps: (new-object net.webclient).DownloadFile('https://raw.github.com/pypa/pip/master/contrib/get-pip.py', 'C:/get-pip.py')
- - "%WITH_COMPILER% %PYTHON%/python.exe -m pip --version"
- - "%WITH_COMPILER% %PYTHON%/python.exe -m pip install --upgrade --user psutil bottle requests netifaces chevron py-cpuinfo scandir"
- - "%WITH_COMPILER% %PYTHON%/python.exe -m pip freeze"
- - "%WITH_COMPILER% %PYTHON%/python.exe setup.py install"
-
-build: off
-
-test_script:
- - "%WITH_COMPILER% %PYTHON%/python -V"
- - "%WITH_COMPILER% %PYTHON%/python unitest.py"
-
-artifacts:
- - path: dist\*
-
-# on_success:
-# - might want to upload the content of dist/*.whl to a public wheelhouse
-
-skip_commits:
- message: skip-ci
diff --git a/glances/plugins/glances_network.py b/glances/plugins/glances_network.py
index 62715bd2..ed8e648a 100644
--- a/glances/plugins/glances_network.py
+++ b/glances/plugins/glances_network.py
@@ -268,6 +268,10 @@ class Plugin(GlancesPlugin):
# Add specifics information
# Alert
for i in self.get_raw():
+ if i['time_since_update'] == 0:
+ # Skip alert if no timespan to measure
+ continue
+
if_real_name = i['interface_name'].split(':')[0]
# Convert rate in bps (to be able to compare to interface speed)
bps_rx = int(i['rx'] // i['time_since_update'] * 8)
diff --git a/unitest.py b/unitest.py
index ca9703a9..f68d7536 100755
--- a/unitest.py
+++ b/unitest.py
@@ -400,9 +400,13 @@ class TestGlances(unittest.TestCase):
def test_100_secure(self):
"""Test secure functions"""
print('INFO: [TEST_100] Secure functions')
- self.assertEqual(secure_popen('echo -n TEST'), 'TEST')
- self.assertEqual(secure_popen('echo FOO | grep FOO'), 'FOO\n')
- self.assertEqual(secure_popen('echo -n TEST1 && echo -n TEST2'), 'TEST1TEST2')
+ if WINDOWS:
+ self.assertEqual(secure_popen('echo TEST'), 'TEST\r\n')
+ self.assertEqual(secure_popen('echo TEST1 && echo TEST2'), 'TEST1\r\nTEST2\r\n')
+ else:
+ self.assertEqual(secure_popen('echo -n TEST'), 'TEST')
+ self.assertEqual(secure_popen('echo FOO | grep FOO'), 'FOO\n')
+ self.assertEqual(secure_popen('echo -n TEST1 && echo -n TEST2'), 'TEST1TEST2')
def test_200_memory_leak(self):
"""Memory leak check"""