Skip to content

Commit

Permalink
Use GitHub actions for CI testing (#702)
Browse files Browse the repository at this point in the history
This PR includes:
- Add a GitHub Actions workflow for CI testing
- Remove Travis CI support
- Move test/ to tests/ (unittest standard?)
- Fix a coloring issue in xbmcextra
- Various new fixes to tracebacks in GitHub CI
  • Loading branch information
dagwieers authored Mar 24, 2020
1 parent b114922 commit a58decf
Show file tree
Hide file tree
Showing 41 changed files with 153 additions and 116 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: CI
on:
push:
branches:
- master
- tests-overhaul
pull_request:
branches:
- master
- tests-overhaul
jobs:
tests:
name: Add-on testing
runs-on: ubuntu-latest
env:
PYTHONIOENCODING: utf-8
PYTHONPATH: ${{ github.workspace }}/resources/lib:${{ github.workspace }}/tests
strategy:
fail-fast: false
matrix:
# max-parallel: 2
python-version: [ 2.7, 3.5, 3.6, 3.7, 3.8 ]
steps:
- name: Check out ${{ github.sha }} from repository ${{ github.repository }}
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get install gettext
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tox
run: python -m tox -q
- name: Run pylint
run: python -m pylint resources/lib/ tests/
- name: Compare translations
run: make check-translations
# Python 2.7 and Python 3.5 are no longer supported by proxy.py
- name: Start proxy server, when supported
run: python -m proxy --hostname 127.0.0.1 --log-level DEBUG &
# if: contains([ '3.6', '3.7', '3.8' ], matrix.python-version)
if: matrix.python-version == '3.6' || matrix.python-version == '3.7' || matrix.python-version == '3.8'
- name: Run unit tests
run: coverage run -m unittest discover
env:
ADDON_PASSWORD: ${{ secrets.ADDON_PASSWORD }}
ADDON_USERNAME: ${{ secrets.ADDON_USERNAME }}
- name: Run addon service
run: coverage run resources/lib/service_entry.py
- name: Run addon using cli
run: coverage run tests/run.py /
- name: Upload code coverage
uses: codecov/codecov-action@v1
11 changes: 6 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ kodi-addon-checker-report.log

# Temporary
experiment/
nohup.out

# Userdata
test/cdm/
test/userdata/cache/
test/userdata/credentials.json
test/userdata/search_history.json
test/userdata/tokens/
tests/cdm/
tests/userdata/cache/
tests/userdata/credentials.json
tests/userdata/search_history.json
tests/userdata/tokens/
32 changes: 0 additions & 32 deletions .travis.yml

This file was deleted.

60 changes: 32 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export PYTHONPATH := $(CURDIR)/resources/lib:$(CURDIR)/test
export PYTHONPATH := $(CURDIR)/resources/lib:$(CURDIR)/tests
PYTHON := python

name = $(shell xmllint --xpath 'string(/addon/@id)' addon.xml)
Expand All @@ -20,63 +20,67 @@ blue = \e[1;34m
white = \e[1;37m
reset = \e[0;39m

.PHONY: test
all: check test build
zip: build
test: check test-unit test-service test-run

all: test zip
check: check-tox check-pylint check-translations

package: zip

test: sanity unit run

sanity: tox pylint language

tox:
check-tox:
@echo -e "$(white)=$(blue) Starting sanity tox test$(reset)"
$(PYTHON) -m tox -q

pylint:
check-pylint:
@echo -e "$(white)=$(blue) Starting sanity pylint test$(reset)"
$(PYTHON) -m pylint resources/lib/ test/
$(PYTHON) -m pylint resources/lib/ tests/

language:
check-translations:
@echo -e "$(white)=$(blue) Starting language test$(reset)"
@-$(foreach lang,$(languages), \
msgcmp resources/language/resource.language.$(lang)/strings.po resources/language/resource.language.en_gb/strings.po; \
)

addon: clean
check-addon: clean
@echo -e "$(white)=$(blue) Starting sanity addon tests$(reset)"
kodi-addon-checker . --branch=krypton
kodi-addon-checker . --branch=leia

unit: clean
@echo -e "$(white)=$(blue) Starting unit tests$(reset)"
check-codecov:
@echo -e "$(white)=$(blue) Test codecov.yml syntax$(reset)"
curl --data-binary @codecov.yml https://codecov.io/validate

kill-proxy:
-pkill -ef '$(PYTHON) -m proxy'
$(PYTHON) -m proxy &

unit: test-unit
run: test-run

test-unit: clean kill-proxy
@echo -e "$(white)=$(blue) Starting unit tests$(reset)"
-$(PYTHON) -m proxy --hostname 127.0.0.1 --log-level DEBUG &
$(PYTHON) -m unittest discover
pkill -ef '$(PYTHON) -m proxy'
-pkill -ef '$(PYTHON) -m proxy'

run:
@echo -e "$(white)=$(blue) Run CLI$(reset)"
test-service:
@echo -e "$(white)=$(blue) Run service$(reset)"
$(PYTHON) resources/lib/service_entry.py
$(PYTHON) test/run.py $(path)

test-run:
@echo -e "$(white)=$(blue) Run CLI$(reset)"
$(PYTHON) tests/run.py $(path)

profile:
@echo -e "$(white)=$(blue) Profiling $(white)$(path)$(reset)"
$(PYTHON) -m cProfile -o profiling_stats-$(git_branch)-$(git_hash).bin test/run.py $(path)
$(PYTHON) -m cProfile -o profiling_stats-$(git_branch)-$(git_hash).bin tests/run.py $(path)

zip: clean
build: clean
@echo -e "$(white)=$(blue) Building new package$(reset)"
@rm -f ../$(zip_name)
cd ..; zip -r $(zip_name) $(include_paths) -x $(exclude_files)
@echo -e "$(white)=$(blue) Successfully wrote package as: $(white)../$(zip_name)$(reset)"

codecov:
@echo -e "$(white)=$(blue) Test .codecov.yml syntax$(reset)"
curl --data-binary @.github/codecov.yml https://codecov.io/validate

clean:
find . -name '*.py[cod]' -type f -delete
find . -name '__pycache__' -type d -delete
rm -rf .pytest_cache/ .tox/
rm -f *.log test/userdata/tokens/*.tkn
rm -f *.log tests/userdata/tokens/*.tkn
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![GitHub release](https://img.shields.io/github/release/pietje666/plugin.video.vrt.nu.svg)](https://github.com/pietje666/plugin.video.vrt.nu/releases)
[![Build Status](https://travis-ci.org/pietje666/plugin.video.vrt.nu.svg?branch=master)](https://travis-ci.org/pietje666/plugin.video.vrt.nu)
[![Build status](https://github.com/pietje666/plugin.video.vrt.nu/workflows/CI/badge.svg)](https://github.com/pietje666/plugin.video.vrt.nu/actions)
[![Codecov status](https://img.shields.io/codecov/c/github/pietje666/plugin.video.vrt.nu/master)](https://codecov.io/gh/pietje666/plugin.video.vrt.nu/branch/master)
[![License: GPLv3](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://opensource.org/licenses/GPL-3.0)
[![Contributors](https://img.shields.io/github/contributors/pietje666/plugin.video.vrt.nu.svg)](https://github.com/pietje666/plugin.video.vrt.nu/graphs/contributors)
Expand Down
2 changes: 1 addition & 1 deletion .codecov.yml → codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ coverage:
patch: false
comment: false
ignore:
- test/
- tests/
8 changes: 5 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ codecov
git+git://github.com/emilsvennesson/script.module.inputstreamhelper.git@master#egg=inputstreamhelper
kodi-addon-checker
polib
proxy.py==0.3
#proxy.py == 0.3; python_version != '2.7'
proxy.py; python_version != '2.7'
python-dateutil
pylint
git+git://github.com/tamland/kodi-plugin-routing.git@master#egg=routing
setuptools >= 41
tox-travis
xmlschema==1.0.18; python_version == '2.7'
tox
typing-extensions == 3.7.4.1; python_version != '2.7'
xmlschema == 1.0.18; python_version == '2.7'
8 changes: 4 additions & 4 deletions resources/language/resource.language.nl_nl/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ msgstr "InputStream Helper informatie"

msgctxt "#30911"
msgid "InputStream Helper settings… [COLOR=gray][I](for protected content)[/I][/COLOR]"
msgstr "InputStream Helper instellingen…[COLOR=gray][I](voor beveiligde video's)[/I][/COLOR]"
msgstr "InputStream Helper instellingen… [COLOR=gray][I](voor beveiligde video's)[/I][/COLOR]"

msgctxt "#30913"
msgid "Cache"
Expand Down Expand Up @@ -834,11 +834,11 @@ msgstr "Maak lokale HTTP caches ongeldig"

msgctxt "#30927"
msgid "Direct HTTP cache time-to-live [COLOR=gray](in minutes)[/COLOR]"
msgstr "Directe HTTP cache time-to-live [COLOR=gray](in minuten)[/COLOR]"
msgstr "Directe HTTP cache levensduur [COLOR=gray](in minuten)[/COLOR]"

msgctxt "#30929"
msgid "Indirect HTTP cache time-to-live [COLOR=gray](in minutes)[/COLOR]"
msgstr "Indirecte HTTP cache time-to-live [COLOR=gray](in minuten)[/COLOR]"
msgstr "Indirecte HTTP cache levensduur [COLOR=gray](in minuten)[/COLOR]"

msgctxt "#30931"
msgid "Logging"
Expand Down Expand Up @@ -956,4 +956,4 @@ msgstr "VRT tokens werden verwijderd."

msgctxt "#30986"
msgid "No on demand stream available for {title}."
msgstr "Geen on demand stream beschikbaar voor {title}"
msgstr "Geen on demand stream beschikbaar voor {title}."
2 changes: 1 addition & 1 deletion resources/lib/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ def list_channels(self, channels=None, live=True):
label = localize(30141, **channel) # Channel live
playing_now = _tvguide.playing_now(channel.get('name'))
if playing_now:
label += ' [COLOR yellow]| %s[/COLOR]' % playing_now
label += ' [COLOR=yellow]| %s[/COLOR]' % playing_now
# A single Live channel means it is the entry for channel's TV Show listing, so make it stand out
if channels and len(channels) == 1:
label = '[B]%s[/B]' % label
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/kodiutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ def get_json_data(response, fail=None):
"""Return json object from HTTP response"""
from json import load, loads
try:
if (3, 0, 0) <= version_info <= (3, 5, 9): # the JSON object must be str, not 'bytes'
if (3, 0, 0) <= version_info < (3, 6, 0): # the JSON object must be str, not 'bytes'
return loads(to_unicode(response.read()))
return load(response)
except TypeError as exc: # 'NoneType' object is not callable
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/resumepoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def resumepoint_headers(url=None):
"""Generate http headers for VRT NU Resumepoints API"""
from tokenresolver import TokenResolver
xvrttoken = TokenResolver().get_xvrttoken(token_variant='user')
headers = None
headers = {}
if xvrttoken:
url = 'https://www.vrt.be' + url if url else 'https://www.vrt.be/vrtnu'
headers = {
Expand Down
9 changes: 7 additions & 2 deletions resources/lib/tokenresolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def _get_cached_token(self, token_name, token_variant=None):
now = datetime.now(dateutil.tz.tzlocal())
exp = dateutil.parser.parse(token.get('expirationDate'))
if exp <= now:
log(2, "Cached token '{path}' deleted", path=path)
log(2, "Token expired, cached token '{path}' deleted", path=path)
delete(path)
return None

Expand Down Expand Up @@ -298,7 +298,8 @@ def _get_roaming_xvrttoken(self, xvrttoken):
@staticmethod
def _create_token_dictionary(cookie_data, cookie_name='X-VRT-Token'):
"""Create a dictionary with token name and token expirationDate from a Python cookielib.CookieJar or urllib2 Set-Cookie http header"""
token_dictionary = None
if cookie_data is None:
return None
if isinstance(cookie_data, cookielib.CookieJar):
# Get token dict from cookiejar
token_cookie = next((cookie for cookie in cookie_data if cookie.name == cookie_name), None)
Expand All @@ -308,6 +309,8 @@ def _create_token_dictionary(cookie_data, cookie_name='X-VRT-Token'):
token_cookie.name: token_cookie.value,
'expirationDate': datetime.utcfromtimestamp(token_cookie.expires).strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
}
else:
token_dictionary = None
elif cookie_name in cookie_data:
# Get token dict from http header
import dateutil.parser
Expand All @@ -316,6 +319,8 @@ def _create_token_dictionary(cookie_data, cookie_name='X-VRT-Token'):
cookie_name: cookie_data[0],
'expirationDate': dateutil.parser.parse(cookie_data[2].strip('Expires=')).strftime('%Y-%m-%dT%H:%M:%S.%fZ')
}
else:
token_dictionary = None
return token_dictionary

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions resources/lib/tvguide.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@ def get_episode_items(self, date, channel):

info_labels = self._metadata.get_info_labels(episode, date=date, channel=entry)
# FIXME: Due to a bug in Kodi, ListItem.Title is used when Sort methods are used, not ListItem.Label
info_labels['title'] = label
info_labels['title'] = colour(label)

episode_items.append(TitleItem(
label=label,
label=colour(label),
path=path,
art_dict=self._metadata.get_art(episode),
info_dict=info_labels,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions test/test_proxy.py → tests/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
plugin = addon.plugin


@unittest.skipIf(sys.version_info[0] < 3, 'Skipping proxy tests on Python 2')
@unittest.skipIf(sys.version_info < (3, 6, 0), 'Skipping proxy tests on Python 3.5 and older')
class TestProxy(unittest.TestCase):
"""TestCase class"""

def setUp(self):
"""Build up function for TestCase class"""
xbmc.settings['network.usehttpproxy'] = True
xbmc.settings['network.httpproxytype'] = 0
xbmc.settings['network.httpproxyserver'] = '127.0.0.1'
xbmc.settings['network.httpproxyserver'] = 'localhost'
xbmc.settings['network.httpproxyport'] = '8899'

def tearDown(self):
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit a58decf

Please sign in to comment.