Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add unittest TestAppBase, which sets up the app and adds the admin user for further tests. #27

Merged
merged 1 commit into from
Jun 28, 2019
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
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Config file for automatic testing at travis-ci.org
sudo: true # http://docs.travis-ci.com/user/migrating-from-legacy/
language: python
python:
- 2.7
install:
- sudo ./travis_install.sh
- sudo ./tests/installTestDb.sh
script:
- nose2 -v
1 change: 1 addition & 0 deletions install/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ DATABASE_URI = '${config_db_uri}'
COLLECTOR_UDP_PORT = ${config_collector_udp}
COLLECTOR_SSL_PORT = ${config_collector_ssl}
NETWORK_INTERFACE = ${network_interface}
TESTING = False
" > "${dir}/../config.py"
echo "* Making necessary scripts executable (if they aren't already)"
chmod +x "${dir}/../bin/pipotd" "${dir}/../bin/create_image.sh" "${dir}/../../client/bin/chroot.sh" >> "$install_log" 2>&1
Expand Down
4 changes: 3 additions & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ def install_secret_keys(application, secret_session='secret_key',
if do_exit:
sys.exit(1)

install_secret_keys(app)

if not app.config['TESTING']:
install_secret_keys(app)


# Expose submenu method for jinja templates
Expand Down
49 changes: 49 additions & 0 deletions tests/installTestDb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
date=`date +%Y-%m-%d`
install_log="${dir}/TestDbSetUp_${date}_log.txt"
read -e -p "Password of the 'root' user of MySQL: " -i "" db_root_password
# Verify password
while ! mysql -u root --password="${db_root_password}" -e ";" ; do
read -e -p "Invalid password, please retry: " -i "" db_root_password
done
db_user="pipot"
db_name="pipotTest"
mysql -u root --password="${db_root_password}" -e "CREATE DATABASE IF NOT EXISTS ${db_name};" >> "$install_log" 2>&1
# Check if DB exists
db_exists=`mysql -u root --password="${db_root_password}" -se"USE ${db_name};" 2>&1`
if [ ! "${db_exists}" == "" ]; then
echo "Failed to create the database! Please check the installation log!"
exit -1
fi
# Check if user exists
db_user_exists=`mysql -u root --password="${db_root_password}" -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '${db_user}')"`
db_user_password=""
if [ ${db_user_exists} = 0 ]; then
rand_pass=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
read -e -p "Password for ${db_user} (will be created): " -i "${rand_pass}" db_user_password
# Attempt to create the user
mysql -u root --password="$db_root_password" -e "CREATE USER '${db_user}'@'localhost' IDENTIFIED BY '${db_user_password}';" >> "$install_log" 2>&1
db_user_exists=`mysql -u root --password="$db_root_password" -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$db_user')"`
if [ ${db_user_exists} = 0 ]; then
echo "Failed to create the user! Please check the installation log!"
exit -1
fi
else
read -e -p "Password for ${db_user}: " db_user_password
# Check if we have access
while ! mysql -u "${db_user}" --password="${db_user_password}" -e ";" ; do
read -e -p "Invalid password, please retry: " -i "" db_user_password
done
fi
# Grant user access to database
mysql -u root --password="${db_root_password}" -e "GRANT ALL ON ${db_name}.* TO '${db_user}'@'localhost';" >> "$install_log" 2>&1
# Check if user has access
db_access=`mysql -u "${db_user}" --password="${db_user_password}" -se"USE ${db_name};" 2>&1`
if [ ! "${db_access}" == "" ]; then
echo "Failed to grant user access to database! Please check the installation log!"
exit -1
fi

echo "# Auto-generated configuration by installTestDb.sh
DATABASE_URI = 'mysql+pymysql://${db_user}:${db_user_password}@localhost:3306/${db_name}'
" > "${dir}/tests/config.py"
110 changes: 110 additions & 0 deletions tests/testAppBase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import os
import sys
import mock
import unittest
from mock import patch


from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
from sqlalchemy.orm import scoped_session, sessionmaker

# Need to append server root path to ensure we can import the necessary files.
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import tests.config
from collections import namedtuple
from flask import g, current_app
from database import create_session, Base
from mod_auth.models import User, Role, Page, PageAccess
from mod_config.models import Service, Notification, Actions, Conditions, Rule
from mod_honeypot.models import Profile, PiModels, PiPotReport, ProfileService, \
CollectorTypes, Deployment


def generate_keys(tempdir):
secret_csrf_path = os.path.join(tempdir, "secret_csrf")
secret_key_path = os.path.join(tempdir, "secret_key")
if not os.path.exists(secret_csrf_path):
secret_csrf_cmd = "head -c 24 /dev/urandom > {path}".format(path=secret_csrf_path)
os.system(secret_csrf_cmd)
if not os.path.exists(secret_key_path):
secret_key_cmd = "head -c 24 /dev/urandom > {path}".format(path=secret_key_path)
os.system(secret_key_cmd)

return {'secret_csrf_path': secret_csrf_path, 'secret_key_path': secret_key_path}


def load_config(tempdir):
key_paths = generate_keys(tempdir)
with open(key_paths['secret_key_path'], 'rb') as secret_key_file:
secret_key = secret_key_file.read()
with open(key_paths['secret_csrf_path'], 'rb') as secret_csrf_file:
secret_csrf = secret_csrf_file.read()

return {
'TESTING': True,
'WTF_CSRF_ENABLED': False,
'SQLALCHEMY_POOL_SIZE': 1,
'SECRET_KEY': secret_key,
'CSRF_SESSION_KEY': secret_csrf,
'SERVER_IP': '127.0.0.1',
'SERVER_PORT': 443,
'INSTANCE_NAME': 'testInstance',
'APPLICATION_ROOT': '/',
'CSRF_ENABLED': False,
'DATABASE_URI': tests.config.DATABASE_URI,
'COLLECTOR_UDP_PORT': 1234,
'COLLECTOR_SSL_PORT': 1235
}


class TestAppBaseTest(unittest.TestCase):
tempdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp")

def create_app(self):
with patch('config_parser.parse_config', return_value=load_config(self.tempdir)):
from run import app
return app

def create_admin(self):
# test if there is admin existed
db = create_session(self.app.config['DATABASE_URI'], drop_tables=False)
role = Role(name="Admin")
db.add(role)
db.commit()
admin_user = User(role_id=role.id, name="Admin", password="admin", email="admin@sample.com")
db.add(admin_user)
db.commit()
db.remove()
return admin_user

def setUp(self):
if not os.path.exists(self.tempdir):
os.mkdir(self.tempdir)
self.app = self.create_app()

def tearDown(self):
db_engine = create_engine(self.app.config['DATABASE_URI'], convert_unicode=True)
Base.metadata.drop_all(bind=db_engine)

def test_app_is_running(self):
self.assertFalse(current_app is None)

def test_app_is_testing(self):
self.assertTrue(self.app.config['TESTING'])

def admin_is_created(self):
db = create_session(self.app.config['DATABASE_URI'], drop_tables=False)
admin_row = Role.query.filter(Role.is_admin).first()
admin = User.query.filter(User.role_id == admin_row.id).first()
db.remove()
return admin is not None

def test_create_admin(self):
self.create_admin()
self.assertTrue(self.admin_is_created())


if __name__ == '__main__':
unittest.main()
15 changes: 12 additions & 3 deletions tests/TestNestedMenus.py → tests/testNestedMenus.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import unittest
import os
import sys

from mock import patch, call
from server.decorators import get_menu_entries, get_permissible_entries
# Need to append server root path to ensure we can import the necessary files.
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from decorators import get_menu_entries, get_permissible_entries


class TestGetMenuEntries(unittest.TestCase):

@patch('mod_auth.models.User')
@patch('server.decorators.get_permissible_entries')
@patch('decorators.get_permissible_entries')
def test_get_menu_entries_with_simple_entries(self, mock_permissible_entries, mock_user):
"""
Passing a menu entry to get_menu_entries() when all the
Expand Down Expand Up @@ -59,7 +64,7 @@ def side_effect(*args):
mock_permissible_entries.assert_has_calls(calls) # Check that mocked function correctly called

@patch('mod_auth.models.User')
@patch('server.decorators.get_permissible_entries')
@patch('decorators.get_permissible_entries')
def test_get_menu_entries_with_no_permissions(self, mock_permissible_entries, mock_user):
"""
Passing a menu entry to get_menu_entries() when user is not
Expand Down Expand Up @@ -158,3 +163,7 @@ def side_effect(*args):
'entries': [{'title': 'Honeypot services', 'route': 'config.services', 'icon': 'sliders'}],
'icon': 'bell-o'}], 'icon': 'bell-o'}
self.assertDictEqual(entries, correct_entries)


if __name__ == "__main__":
unittest.main()
21 changes: 21 additions & 0 deletions travis_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
echo "-------------------------------"
echo "| Installing dependencies |"
echo "-------------------------------"
echo ""
echo "* Updating package list "
apt-get update
echo "* Installing nginx, python & pip "

apt-get -q -y install dnsutils nginx python python-dev python-pip

if [[ "$OSTYPE" == "linux-gnu" ]]; then
apt-get -q -y install build-essential libffi-dev libssl-dev
fi
if [ ! -f /etc/init.d/mysql* ]; then
echo "* Installing MySQL (root password will be empty!)"
DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server
fi
echo "* Update setuptools "
pip install --upgrade setuptools
echo "* Installing pip dependencies"
pip install nose2 mock ipaddress enum34 cryptography idna sqlalchemy twisted pyopenssl flask-sqlalchemy flask passlib pymysql service_identity pycrypto flask-wtf netifaces gunicorn