Skip to content

Commit

Permalink
ci: test with github action (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
everpcpc authored Jan 11, 2022
1 parent 2a0a1f3 commit 152d761
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 55 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Publish

on:
push:
tags:
- v*

jobs:
pypi:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Build a source tarball
run: python setup.py sdist
- name: Build wheels
uses: RalfG/python-wheels-manylinux-build@v0.3.4-manylinux1_x86_64
with:
python-versions: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310'
build-requirements: 'cython'
- name: Clean linux_x86_64.whl
run: rm dist/*-linux_x86_64.whl
- name: Check build result
run: ls -lh dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip_existing: true
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Test

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
unittest:
runs-on: ubuntu-latest
strategy:
matrix:
pyver: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"]

steps:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.pyver }}
- name: Install python dependencies
run: |
python -m pip install --upgrade pip
pip install Cython tox
- name: Run unittest
run: |
tox -e ${{ matrix.pyver }}
File renamed without changes.
22 changes: 14 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
greenify_
=========

|build| |status| |pypiv| |pyversions| |wheel| |license|

greenify_ can make Python extension modules having network operations in C
code to be compatible with gevent_.

greenify_ uses the Dynamic Function Redirecting technique same as ELF-Hook_
greenify_ uses the Dynamic Function Redirecting technique same as ELF-Hook_
to patch blocking network operations at runtime, without the need modify
the original modules.

Currently greenify_ only supports ELF format modules, and is tested on Linux.

Build status
------------

- Branch **master** : |travis_master|

.. |travis_master| image:: https://travis-ci.org/douban/greenify.svg?branch=master
:target: https://travis-ci.org/douban/greenify

Install from source
-------------------
Expand Down Expand Up @@ -64,3 +59,14 @@ greenify_ is written and maintained by `douban`_ and is licensed under New BSD l
.. _greenify: https://github.com/douban/greenify
.. _douban: http://www.douban.com
.. _ELF-Hook: https://github.com/shoumikhin/ELF-Hook

.. |build| image:: https://github.com/douban/greenify/actions/workflows/test.yml/badge.svg
:target: https://github.com/douban/greenify/actions/workflows/test.yml

.. |pypiv| image:: https://img.shields.io/pypi/v/greenify
:target: https://pypi.org/project/greenify/

.. |status| image:: https://img.shields.io/pypi/status/greenify
.. |pyversions| image:: https://img.shields.io/pypi/pyversions/greenify
.. |wheel| image:: https://img.shields.io/pypi/wheel/greenify
.. |license| image:: https://img.shields.io/pypi/l/greenify?color=blue
File renamed without changes.
2 changes: 1 addition & 1 deletion misc/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ python fake_slow_http_server.py&
pid=$!
pip install .
python test.py
kill $pid
kill $pid || true
6 changes: 3 additions & 3 deletions tests/http_head/fake_slow_http_server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding: utf-8

import time

try:
from SimpleHTTPServer import SimpleHTTPRequestHandler
from SocketServer import TCPServer
Expand All @@ -18,15 +19,14 @@ class Server(TCPServer):


class Handler(SimpleHTTPRequestHandler):

def do_HEAD(self):
time.sleep(BLOCKING_SECONDS)
return SimpleHTTPRequestHandler.do_HEAD(self)


if __name__ == '__main__':
if __name__ == "__main__":
httpd = Server(("", PORT), Handler)
try:
httpd.serve_forever()
except:
except Exception:
httpd.server_close()
27 changes: 15 additions & 12 deletions tests/http_head/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@
import platform
from distutils.core import setup, Extension

virtualenv_path = os.environ.get('VIRTUAL_ENV')
virtualenv_path = os.environ.get("VIRTUAL_ENV")

include_dirs = list(filter(None, [os.environ.get('INCLUDE_DIRS')]))
library_dirs = list(filter(None, [os.environ.get('LIBRARY_DIRS')]))
include_dirs = list(filter(None, [os.environ.get("INCLUDE_DIRS")]))
library_dirs = list(filter(None, [os.environ.get("LIBRARY_DIRS")]))

if virtualenv_path:
include_dirs.append('%s/include' % virtualenv_path)
library_dirs.append('%s/lib' % virtualenv_path)
ld_lib_key = ('DYLD_LIBRARY_PATH' if platform.platform() == 'Darwin'
else 'LD_LIBRARY_PATH')
os.environ[ld_lib_key] = '%s/lib' % virtualenv_path
include_dirs.append("%s/include" % virtualenv_path)
library_dirs.append("%s/lib" % virtualenv_path)
ld_lib_key = "DYLD_LIBRARY_PATH" if platform.platform() == "Darwin" else "LD_LIBRARY_PATH"
os.environ[ld_lib_key] = "%s/lib" % virtualenv_path

mod_http_head = Extension(
'mod_http_head', sources=['mod_http_head.c'],
"mod_http_head",
sources=["mod_http_head.c"],
include_dirs=include_dirs,
library_dirs=library_dirs,
)

setup(name='mod_http_head', version='1.0',
description='A demo package http_head greenified',
ext_modules=[mod_http_head])
setup(
name="mod_http_head",
version="1.0",
description="A demo package http_head greenified",
ext_modules=[mod_http_head],
)
65 changes: 35 additions & 30 deletions tests/http_head/test.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
# coding: utf-8
from __future__ import print_function

import sys
import time

# greenify
import greenify

greenify.greenify()

# python patch
import gevent
import gevent.monkey
import gevent # noqa: E402
import gevent.monkey # noqa: E402

gevent.monkey.patch_all()

import sys
import time
import mod_http_head
import mod_http_head # noqa: E402

assert greenify.patch_lib(mod_http_head.__file__)
import fake_slow_http_server
import fake_slow_http_server # noqa: E402

stack = []


def c_http_head_check(addr):
stack.append(('begin', addr, 'c'))
print('%.5f head %s begin' % (time.time(), addr), file=sys.stderr)
stack.append(("begin", addr, "c"))
print("%.5f head %s begin" % (time.time(), addr), file=sys.stderr)
ret = mod_http_head.http_head(*addr)
print('%.5f head %s end' % (time.time(), addr), file=sys.stderr)
stack.append(('end', addr, 'c'))
print("%.5f head %s end" % (time.time(), addr), file=sys.stderr)
stack.append(("end", addr, "c"))
assert ret == 1


Expand All @@ -34,50 +38,51 @@ def python_http_head_check(addr):
except ImportError:
from http.client import HTTPConnection

stack.append(('begin', addr, 'python'))
print('%.5f head %s begin' % (time.time(), addr), file=sys.stderr)
stack.append(("begin", addr, "python"))
print("%.5f head %s begin" % (time.time(), addr), file=sys.stderr)
conn = HTTPConnection(*addr)
conn.request("HEAD", "/")
resp = conn.getresponse()
status_code = resp.status
print('%.5f head %s end' % (time.time(), addr), file=sys.stderr)
stack.append(('end', addr, 'python'))
print("%.5f head %s end" % (time.time(), addr), file=sys.stderr)
stack.append(("end", addr, "python"))
assert 200 <= status_code < 400


def sleeper():
stack.append(('begin', 'sleeper'))
print('%.5f sleeper begin' % time.time(), file=sys.stderr)
time.sleep(fake_slow_http_server.BLOCKING_SECONDS/2)
print('%.5f sleeper end' % time.time(), file=sys.stderr)
stack.append(('end', 'sleeper'))
stack.append(("begin", "sleeper"))
print("%.5f sleeper begin" % time.time(), file=sys.stderr)
time.sleep(fake_slow_http_server.BLOCKING_SECONDS / 2)
print("%.5f sleeper end" % time.time(), file=sys.stderr)
stack.append(("end", "sleeper"))


def main():
global stack
local_addr = ("localhost", str(fake_slow_http_server.PORT))
test_sites = (local_addr, ("google.com", "80"), ("twitter.com", "80"),
("douban.com", "80"), ("github.com", "80"))
test_sites = (
local_addr,
("google.com", "80"),
("twitter.com", "80"),
("douban.com", "80"),
("github.com", "80"),
)
for fn in [python_http_head_check, c_http_head_check]:
stack = []
print('test %s' % fn.__name__)
print("test %s" % fn.__name__)
t0 = time.time()
workers = [
gevent.spawn(fn, addr)
for addr in test_sites
]
workers = [gevent.spawn(fn, addr) for addr in test_sites]
workers.append(gevent.spawn(sleeper))

gevent.joinall(workers)
time_elapsed = time.time() - t0
print('done in %.5fs' % (time_elapsed))
print("done in %.5fs" % (time_elapsed))
print()
# HEAD to fake_slow_http_server is expected to
# be the slowest worker
assert stack[-1][:2] == ('end', local_addr), \
"unexpected: %r" % (stack[-1][:2], )
assert stack[-1][:2] == ("end", local_addr), "unexpected: %r" % (stack[-1][:2],)
assert time_elapsed < fake_slow_http_server.BLOCKING_SECONDS * 1.5


if __name__ == '__main__':
if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ envlist = py27, py35, py36, py37, py38, py39, py310
[testenv]
passenv = CC LD
deps = -rreq.txt
commands = {toxinidir}/misc/test.sh
commands = {toxinidir}/misc/test.sh

0 comments on commit 152d761

Please sign in to comment.