Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CI

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

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install -r requirements-dev.txt

- name: Run pytest
run: |
PYTHONPATH=. pytest -q

- name: Run behave
run: |
PYTHONPATH=. behave -f progress2

10 changes: 10 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[MASTER]
# Ignore BDD test steps; they rely on runtime-provided globals
ignore=features

[MESSAGES CONTROL]
# No global disables; prefer fixing code issues
disable=

[FORMAT]
max-line-length=120
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.PHONY: test-behave

test-behave:
PYTHONPATH=. behave -f progress2
105 changes: 52 additions & 53 deletions examples/example_servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,62 @@
logging.basicConfig(format=FORMAT)

class MyServer(jsocket.ThreadedServer):
""" This is a basic example of a custom ThreadedServer. """
def __init__(self):
super(MyServer, self).__init__()
self.timeout = 2.0
logger.warning("MyServer class in customServer is for example purposes only.")
def _process_message(self, obj):
""" virtual method """
if obj != '':
if obj['message'] == "new connection":
logger.info("new connection.")
return {'message': 'welcome to jsocket server'}
"""This is a basic example of a custom ThreadedServer."""
def __init__(self):
super(MyServer, self).__init__()
self.timeout = 2.0
logger.warning("MyServer class in customServer is for example purposes only.")

def _process_message(self, obj):
""" virtual method """
if obj != '':
if obj['message'] == "new connection":
logger.info("new connection.")
return {'message': 'welcome to jsocket server'}

class MyFactoryThread(jsocket.ServerFactoryThread):
""" This is an example factory thread, which the server factory will
instantiate for each new connection.
"""
def __init__(self):
super(MyFactoryThread, self).__init__()
self.timeout = 2.0
def _process_message(self, obj):
""" virtual method - Implementer must define protocol """
if obj != '':
if obj['message'] == "new connection":
logger.info("new connection...")
return {'message': 'welcome to jsocket server'}
else:
logger.info(obj)
"""This is an example factory thread, which the server factory will
instantiate for each new connection.
"""
def __init__(self):
super(MyFactoryThread, self).__init__()
self.timeout = 2.0

def _process_message(self, obj):
""" virtual method - Implementer must define protocol """
if obj != '':
if obj['message'] == "new connection":
logger.info("new connection...")
return {'message': 'welcome to jsocket server'}
else:
logger.info(obj)

if __name__ == "__main__":
import time
import jsocket

server = jsocket.ServerFactory(MyFactoryThread, address='127.0.0.1', port=5491)
server.timeout = 2.0
server.start()

time.sleep(1)
cPids = []
for i in range(10):
client = jsocket.JsonClient(address='127.0.0.1', port=5491)
cPids.append(client)
client.connect()
client.send_obj({"message": "new connection", "test": i})
logger.info(client.read_obj())
import time
import jsocket

server = jsocket.ServerFactory(MyFactoryThread, address='127.0.0.1', port=5491)
server.timeout = 2.0
server.start()

client.send_obj({"message": i, "key": 1 })

time.sleep(2)

for c in cPids:
c.close()
time.sleep(1)
cPids = []
for i in range(10):
client = jsocket.JsonClient(address='127.0.0.1', port=5491)
cPids.append(client)
client.connect()
client.send_obj({"message": "new connection", "test": i})
logger.info(client.read_obj())

client.send_obj({"message": i, "key": 1 })

time.sleep(2)

for c in cPids:
c.close()

time.sleep(5)
logger.warning("Stopping server")
server.stop()
server.join()
logger.warning("Example script exited")
time.sleep(5)
logger.warning("Stopping server")
server.stop()
server.join()
logger.warning("Example script exited")
20 changes: 9 additions & 11 deletions features/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
Main lettuce repo still doesn't support python3
Use sgpy fork at https://github.com/sgpy/lettuce instead
Python 3 BDD tests use Behave instead of Lettuce.

Remove any existing python2/3 packages
pip uninstall lettuce
pip3 uninstall lettuce
Setup
- Install dependencies: `python -m pip install behave`

Install fork version
git clone https://github.com/sgpy/lettuce
cd lettuce
python3 setup.py install
Run
- From repo root: `PYTHONPATH=. behave -f progress2`

cd python-json-socket
lettuce
Notes
- Feature files live under `features/*.feature` (unchanged from Lettuce).
- Step definitions are in `features/steps/steps.py`.
- Behave will launch a simple server and client to validate JSON message flow.
18 changes: 18 additions & 0 deletions features/environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Behave environment hooks for setup/teardown safety

def after_all(context):
# Best-effort cleanup in case scenarios fail mid-run
server = getattr(context, 'jsonserver', None)
client = getattr(context, 'jsonclient', None)
try:
if client is not None:
client.close()
except Exception: # pragma: no cover - cleanup best-effort
pass
try:
if server is not None:
server.stop()
server.join(timeout=3)
except Exception: # pragma: no cover
pass

65 changes: 0 additions & 65 deletions features/steps.py

This file was deleted.

2 changes: 2 additions & 0 deletions features/steps/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Behave step package marker

Loading