Skip to content

Commit

Permalink
Merge pull request #110 from ethertricity/restore_telnet
Browse files Browse the repository at this point in the history
Restore tcp 'Ok' response
  • Loading branch information
jooste committed Nov 13, 2017
2 parents 41fc812 + ffe3aab commit 8874763
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 72 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ __pycache__/
*.sublime*
*.atom-build*
*.build-tools*
.idea/*

# C extensions
*.so
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.PHONY: test
test:
@python -m pytest bluesky/test
@echo "Running Tests using Python2 BlueSky"
TESTING=true PYEXEC=python2 python3 -m pytest -s bluesky/test
@echo "Running Tests using Python3 BlueSky"
TESTING=true PYEXEC=python3 python3 -m pytest -s bluesky/test
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ containing the same commands with a time stamp before the command ("HH:MM:SS.hh>
## Contributions
BlueSky is still under heavy development. We would like to encourage anyone with a strong interest in
ATM and/or Python to join us. Please feel free to comment, criticise, and contribute to this project.
# bluesky_json_http
7 changes: 5 additions & 2 deletions bluesky/simulation/qtgl/mainmanager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" MainManager manages I/O with the simulation processes on the GUI side. """
from __future__ import print_function
import select
import sys
from subprocess import Popen
Expand All @@ -12,7 +13,7 @@
QCoreApplication as qapp

# Local imports
from bluesky import settings
from bluesky import settings, MSG_OK
from .simevents import SimStateEventType, SimQuitEventType, BatchEventType, \
BatchEvent, StackTextEvent, StackTextEventType, SimQuitEvent, SetNodeIdType, \
SetActiveNodeType, AddNodeType
Expand Down Expand Up @@ -138,7 +139,9 @@ def receiveFromNodes(self):

elif event.type() == StackTextEventType:
self.telnet_in.sendReply(event)
qapp.sendEvent(qapp.instance(), event)

if not event.disptext == MSG_OK:
qapp.sendEvent(qapp.instance(), event)

else:
# The event is meant for the gui
Expand Down
6 changes: 5 additions & 1 deletion bluesky/stack/stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
process() : central command processing method
Created by : Jacco M. Hoekstra (TU Delft)
"""
from __future__ import print_function
from math import *
from random import seed
import re
Expand Down Expand Up @@ -1164,8 +1165,11 @@ def process():
# text: optional error message
if parser.parse():
results = function(*parser.arglist) # * = unpack list to call arguments

if isinstance(results, bool): # Only flag is returned
if not results:
if results:
bs.scr.echo(bs.MSG_OK, sender_id)
else:
if not args:
bs.scr.echo(helptext, sender_id)
else:
Expand Down
53 changes: 52 additions & 1 deletion bluesky/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,56 @@
Author <ahfarrell@sparkl.com> Andrew Farrell
Common test functionality.
NOTE - The test suite is written in Python3 only.
It tests BlueSky running in either Python2 or 3.
"""
from __future__ import print_function
import inspect
import time
from bluesky.tools.network import as_bytes


BLUESKY = "BlueSky_qtgl.py"
BUFFER_SIZE = 1024
TCP_HOST = "127.0.0.1"
TCP_PORT = 8888


def sock_connect(socket_, host, port):
"""
Attempts a socket connection, and returns success boolean.
Args:
socket_: the socket, created with 'socket' method
host:: the host
port: the port
Returns:
whether socket is connected
"""
try:
socket_.connect((host, port))
return True
except ConnectionRefusedError:
return False


def sock_send(socket_, msg):
"""
Sends data across socket.
"""
socket_.send(
as_bytes(msg + "\n"))


def sock_receive(socket_):
"""
Gets data from socket.
"""
data = bytes(socket_.recv(BUFFER_SIZE)).decode('utf8').rstrip()
printrecv(data)
return data


def funname(stackpos):
Expand All @@ -26,6 +72,10 @@ def funname(stackpos):
return inspect.stack()[stackpos][3]


def funname_message(message):
return funname(2) + ":" + str(message)


def printrecv(data, stackpos=2):
"""
Prints the data received by test from bluesky.
Expand All @@ -51,9 +101,10 @@ def wait_for(test, iters, period):
if iter == 0:
raise BlueSkyTestException()

time.sleep(period) # front-load a sleep

success = test()
if not success:
time.sleep(period)
wait_for(test, iters - 1, 2 * period)


Expand Down
47 changes: 47 additions & 0 deletions bluesky/test/tcp/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""
Copyright (c) 2017 SPARKL Limited. All Rights Reserved.
For inclusion with BlueSky upstream code:
https://github.com/ProfHoekstra/bluesky/, distributed under
GNU General Public License v3.
Author <ahfarrell@sparkl.com> Andrew Farrell
Common test fixtures.
NOTE - The test suite is written in Python3 only.
It tests BlueSky running in either Python2 or 3.
"""
from __future__ import print_function
import pytest
import sys
import socket
import os
import psutil
import subprocess
import signal
import bluesky
from .. import sock_connect, wait_for, TCP_HOST, TCP_PORT, BLUESKY


@pytest.fixture(scope="session")
def sock(pytestconfig):
"""
Suite-level setup and teardown function, for those test functions
naming `sock` in their parameter lists.
"""
newpid = os.fork()
if newpid != 0:
sock_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
wait_for(
lambda: sock_connect(sock_, TCP_HOST, TCP_PORT), -1, 5)
yield sock_, bluesky
sock_.close()
parent_pid = os.getpid()
parent = psutil.Process(parent_pid)
children = parent.children(recursive=True)
for child in children:
try:
child.send_signal(signal.SIGKILL)
except psutil.NoSuchProcess:
pass
else:
subprocess.call([os.environ['PYEXEC'], BLUESKY])
90 changes: 24 additions & 66 deletions bluesky/test/tcp/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,8 @@
Author <ahfarrell@sparkl.com> Andrew Farrell
Tests TCP interface.
"""
import os
import sys
import socket
import signal
import psutil
import pytest

BLUESKY = "BlueSky_qtgl.py"
TCP_HOST = "127.0.0.1"
TCP_PORT = 8888
BUFFER_SIZE = 1024

SYNTAX_ERROR = "Syntax error"


@pytest.fixture(scope="module")
def sock(pytestconfig):
"""
Suite-level setup and teardown function, for those test functions
naming `sock` in their parameter lists.
"""
rootdir = str(pytestconfig.rootdir)
sys.path.append(rootdir)
from BlueSky_qtgl import start, gui_prestart, gui_exec, stop
import bluesky
import bluesky.test

tcp, manager = start()
gui_prestart()
newpid = os.fork()
if newpid != 0:
sock_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_.connect((TCP_HOST, TCP_PORT))
yield sock_, bluesky, bluesky.test
sock_.close()
stop(tcp, manager)
parent_pid = os.getpid()
parent = psutil.Process(parent_pid)
child = parent.children(recursive=False)[0]
child.send_signal(signal.SIGKILL)
else:
gui_exec()
from .. import TCP_HOST, TCP_PORT, wait_for, sock_receive, sock_send


def test_create_fail(sock):
Expand All @@ -57,58 +17,56 @@ def test_create_fail(sock):
yields some kind of syntax error, without being rigidly prescriptive
regarding what is returned.
"""
sock_, _blue, blue_test = sock
sock_.send("CRE\n")
data = sock_.recv(BUFFER_SIZE).strip().split("\n")
blue_test.printrecv(data)
assert len(data) == 3
assert SYNTAX_ERROR in data[0]
sock_, _bluesky = sock

sock_send(sock_, "CRE")
data = sock_receive(sock_)
assert data == 'CRE acid,type,lat,lon,hdg,alt,spd'


def test_create_success(sock):
"""
Tests that creating an aircraft properly yields an 'ok.' response.
"""
sock_, blue, blue_test = sock
sock_.send("CRE KL204, B744, 52, 4, 180, 2000, 220\n")
data = sock_.recv(BUFFER_SIZE).strip().split("\n")
blue_test.printrecv(data)
assert len(data) == 1
assert data[0] == blue.MSG_OK
print(sock)
sock_, bluesky = sock

sock_send(sock_, "CRE KL204, B744, 52, 4, 180, 2000, 220")
data = sock_receive(sock_)
assert data == bluesky.MSG_OK


def test_pos(sock):
"""
Tests that we get meaningful information on the aircraft just created.
"""
sock_, _blue, blue_test = sock
sock_.send("POS KL204\n")
data = sock_.recv(BUFFER_SIZE).strip().split("\n")
blue_test.printrecv(data)
assert data[0].startswith("Info on KL204")
assert len(data) > 5
sock_, _bluesky = sock

sock_send(sock_,"POS KL204")
data = sock_receive(sock_)

assert data.startswith("Info on KL204")


def test_disconnect(sock):
"""
Tests that when disconnecting a socket, it is removed from bluesky's
records of active socket connections.
"""
sock_, blue, blue_test = sock
sock_, bluesky = sock

def conns(num_conns):
"""
Tests for appropriate number of connections
as determined by `num_conns`
"""
sock_.send(blue.CMD_TCP_CONNS + "\n")
data = sock_.recv(BUFFER_SIZE).strip().split("\n")
blue_test.printrecv(data, 5)
return num_conns == int(data[0])
sock_send(sock_,bluesky.CMD_TCP_CONNS)
data = sock_receive(sock_)
return num_conns == int(data)

# Open second socket
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock2.connect((TCP_HOST, TCP_PORT))
blue_test.wait_for(lambda: conns(2), 2, 2)
wait_for(lambda: conns(2), 2, 2)
sock2.close()
blue_test.wait_for(lambda: conns(1), 2, 2)
wait_for(lambda: conns(1), 2, 2)
16 changes: 15 additions & 1 deletion bluesky/tools/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
import socket
import threading
import bluesky as bs
import sys


def as_bytes(msg):
"""
Encodes strings to bytes.
"""
if sys.version_info.major == 3:
return msg.encode('utf-8')
else:
return msg


if bs.settings.gui == 'qtgl':
try:
Expand Down Expand Up @@ -41,7 +53,9 @@ def onReadyRead(self):
self.processData(self.readAll())

def sendReply(self, msg):
self.writeData('{}\n'.format(msg))
self.writeData(
as_bytes(
'{}\n'.format(msg)))

def processData(self, data):
# Placeholder function; override it with your own implementation
Expand Down

0 comments on commit 8874763

Please sign in to comment.