2020-12-16 02:10:37 +01:00
|
|
|
import os
|
|
|
|
|
|
|
|
from .context import config_file, TestTimeoutException
|
2018-01-04 18:29:03 +01:00
|
|
|
|
|
|
|
import logging
|
|
|
|
import requests
|
|
|
|
import sys
|
|
|
|
import time
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
from threading import Thread
|
|
|
|
|
|
|
|
from platypush import Daemon
|
|
|
|
from platypush.config import Config
|
|
|
|
from platypush.message import Message
|
|
|
|
from platypush.message.response import Response
|
|
|
|
from platypush.utils import set_timeout, clear_timeout
|
|
|
|
|
2020-12-16 02:10:37 +01:00
|
|
|
|
2018-01-04 18:29:03 +01:00
|
|
|
class TestHttp(unittest.TestCase):
|
|
|
|
""" Tests the full flow of a request/response on the HTTP backend.
|
|
|
|
Runs a remote command over HTTP via shell.exec plugin and gets the output """
|
|
|
|
|
2019-07-15 16:28:44 +02:00
|
|
|
timeout = 10
|
|
|
|
sleep_secs = 10
|
2020-12-16 02:10:37 +01:00
|
|
|
db_file = '/tmp/platypush-tests.db'
|
|
|
|
test_user = 'platypush'
|
|
|
|
test_pass = 'test'
|
|
|
|
base_url = 'http://localhost:8123'
|
|
|
|
expected_registration_redirect = '{base_url}/register?redirect={base_url}/execute'.format(base_url=base_url)
|
|
|
|
expected_login_redirect = '{base_url}/login?redirect={base_url}/execute'.format(base_url=base_url)
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.app = None
|
2018-01-04 18:29:03 +01:00
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
|
|
|
|
backends = Config.get_backends()
|
2020-12-16 02:10:37 +01:00
|
|
|
self.assertTrue('http' in backends, 'Missing HTTP server configuration')
|
2018-01-04 18:29:03 +01:00
|
|
|
|
|
|
|
self.start_daemon()
|
2019-07-15 16:28:44 +02:00
|
|
|
logging.info('Sleeping {} seconds while waiting for the daemon to start up'.format(self.sleep_secs))
|
|
|
|
time.sleep(self.sleep_secs)
|
2020-12-16 02:10:37 +01:00
|
|
|
|
|
|
|
def test_http_flow(self):
|
|
|
|
# An /execute request performed before any user is registered should redirect to the registration page.
|
|
|
|
response = self.send_request()
|
|
|
|
self.assertEqual(self.expected_registration_redirect, response.url,
|
|
|
|
'No users registered, but the application did not redirect us to the registration page')
|
|
|
|
|
|
|
|
# Emulate a first user registration through form and get the session_token.
|
|
|
|
response = self.register_user()
|
|
|
|
self.assertGreater(len(response.history), 0, 'Redirect missing from the history')
|
|
|
|
self.assertTrue('session_token' in response.history[0].cookies, 'No session_token returned upon registration')
|
|
|
|
self.assertEqual('{base_url}/'.format(base_url=self.base_url), response.url,
|
|
|
|
'The registration form did not redirect to the main panel')
|
|
|
|
|
|
|
|
# After a first user has been registered any unauthenticated call to /execute should redirect to /login.
|
|
|
|
response = self.send_request()
|
|
|
|
self.assertEqual(self.expected_login_redirect, response.url,
|
|
|
|
'An unauthenticated request after user registration should result in a login redirect')
|
|
|
|
|
|
|
|
# A request authenticated with user/pass should succeed.
|
|
|
|
response = self.parse_response(self.send_request(auth=(self.test_user, self.test_pass)))
|
|
|
|
self.assertEqual(response.__class__, Response, 'The request did not return a proper Response object')
|
|
|
|
self.assertEqual(response.output.strip(), 'ping', 'The request did not return the expected output')
|
|
|
|
|
|
|
|
# A request with the wrong user/pass should fail.
|
|
|
|
response = self.send_request(auth=('wrong', 'wrong'))
|
|
|
|
self.assertEqual(self.expected_login_redirect, response.url,
|
|
|
|
'A request with wrong credentials should fail')
|
2018-01-04 18:29:03 +01:00
|
|
|
|
|
|
|
def start_daemon(self):
|
|
|
|
def _f():
|
2020-12-16 02:10:37 +01:00
|
|
|
self.app = Daemon(config_file=config_file)
|
|
|
|
self.app.start()
|
2018-01-04 18:29:03 +01:00
|
|
|
|
|
|
|
Thread(target=_f).start()
|
|
|
|
|
2020-12-16 02:10:37 +01:00
|
|
|
@staticmethod
|
|
|
|
def on_timeout(msg):
|
2018-01-04 18:29:03 +01:00
|
|
|
def _f(): raise TestTimeoutException(msg)
|
2020-12-16 02:10:37 +01:00
|
|
|
|
2018-01-04 18:29:03 +01:00
|
|
|
return _f
|
|
|
|
|
2020-12-16 02:10:37 +01:00
|
|
|
def send_request(self, **kwargs):
|
2018-01-04 18:29:03 +01:00
|
|
|
set_timeout(seconds=self.timeout,
|
|
|
|
on_timeout=self.on_timeout('Receiver response timed out'))
|
|
|
|
|
|
|
|
response = requests.post(
|
2020-12-16 02:10:37 +01:00
|
|
|
'{}/execute'.format(self.base_url),
|
|
|
|
json={
|
2018-01-29 16:34:00 +01:00
|
|
|
'type': 'request',
|
|
|
|
'target': Config.get('device_id'),
|
|
|
|
'action': 'shell.exec',
|
2020-12-16 02:10:37 +01:00
|
|
|
'args': {'cmd': 'echo ping'}
|
|
|
|
}, **kwargs
|
2018-01-04 18:29:03 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
clear_timeout()
|
2020-12-16 02:10:37 +01:00
|
|
|
return response
|
|
|
|
|
|
|
|
def register_user(self):
|
|
|
|
set_timeout(seconds=self.timeout,
|
|
|
|
on_timeout=self.on_timeout('User registration response timed out'))
|
|
|
|
|
|
|
|
response = requests.post('{base_url}/register?redirect={base_url}/'.format(base_url=self.base_url), data={
|
|
|
|
'username': self.test_user,
|
|
|
|
'password': self.test_pass,
|
|
|
|
'confirm_password': self.test_pass,
|
|
|
|
})
|
|
|
|
|
|
|
|
clear_timeout()
|
|
|
|
return response
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def parse_response(response):
|
|
|
|
return Message.build(response.json())
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
if self.app:
|
|
|
|
self.app.stop_app()
|
2018-01-04 18:29:03 +01:00
|
|
|
|
2020-12-16 02:10:37 +01:00
|
|
|
if os.path.isfile(self.db_file):
|
|
|
|
os.unlink(self.db_file)
|
2018-01-04 18:29:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|
|
|
|
|
|
|
|
|
2019-07-15 16:28:44 +02:00
|
|
|
# vim:sw=4:ts=4:et:
|