1
0
mirror of https://github.com/linkedin/oncall.git synced 2025-11-29 23:38:17 +02:00
Files
oncall/e2e/conftest.py

246 lines
7.7 KiB
Python
Raw Normal View History

2017-05-02 15:57:25 -07:00
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
#!/usr/bin/env python
import pytest
import requests
from uuid import uuid4
from oncall import db
from testutils import api_v0
import os.path
import yaml
2017-05-02 15:57:25 -07:00
@pytest.fixture(scope="session", autouse=True)
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
def require_db(request):
# Read config based on pytest root directory. Assumes config lives at oncall/configs/config.yaml
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
cfg_path = os.path.join(str(request.config.rootdir), 'configs/config.yaml')
with open(cfg_path) as f:
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
config = yaml.safe_load(f)
db.init(config['db'])
2017-05-02 15:57:25 -07:00
@pytest.fixture(scope="session", autouse=True)
def require_test_user():
re = requests.post(api_v0('users'), json={'name': 'test_user'})
assert re.status_code in [422, 201]
2017-05-02 15:57:25 -07:00
@pytest.fixture(scope="function")
def user(request):
class UserFactory(object):
def __init__(self, prefix):
self.prefix = prefix
self.created = []
def create(self):
name = '_'.join([self.prefix, 'user', str(len(self.created))])
re = requests.post(api_v0('users'), json={'name': name})
assert re.status_code in [201, 422]
self.created.append(name)
return name
def add_to_team(self, user, team):
re = requests.post(api_v0('teams/%s/users' % team), json={'name': user})
assert re.status_code == 201
def add_to_roster(self, user, team, roster):
re = requests.post(api_v0('teams/%s/rosters/%s/users' % (team, roster)),
json={'name': user})
assert re.status_code == 201
def cleanup(self):
for user in self.created:
requests.delete(api_v0('users/' + user))
factory = UserFactory(request.function.prefix)
yield factory
factory.cleanup()
@pytest.fixture(scope="function")
def team(request, user, service):
2017-05-02 15:57:25 -07:00
class TeamFactory(object):
def __init__(self, prefix):
self.prefix = prefix
self.created = set()
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
self.created_ids = set()
2017-05-02 15:57:25 -07:00
self.connection = db.connect()
self.cursor = self.connection.cursor()
def create(self):
name = '_'.join([self.prefix, 'team', str(len(self.created))])
re = requests.post(api_v0('teams'), json={'name': name, 'scheduling_timezone': 'utc'})
assert re.status_code in [201, 422]
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
team_id = requests.get(api_v0('teams/%s' % name)).json()['id']
2017-05-02 15:57:25 -07:00
self.created.add(name)
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
self.created_ids.add(team_id)
2017-05-02 15:57:25 -07:00
return name
def mark_for_cleaning(self, team_name):
self.created.add(team_name)
def cleanup(self):
for team in self.created:
requests.delete(api_v0('teams/' + team))
Py3 (#290) * Py3 migration * Update to Python 3 for CircleCI * Fix auth bugs for python 3 Also fix notifier bug to check for active users * Update notifier exception handling Ignore role:target lookup failures from Iris, since these don't represent problems with the underlying system, just that people have inactive users on-call in the future. * Add get_id param option (#246) * add get_id param option * removed superfluous select and simplified logic * Flake8 typo (#247) * Hide confusing team settings in an advanced dropdown * Fix test fixtures * Add "allow duplicate" scheduler in UI Already in backend, so enable in FE too * Add Dockerfile to run oncall in a container * Move deps into a virtualenv. Run app not as super user. Mimick prod setup by using uwsgi * Fix issue with Dockerfile not having MANIFEST.in and wrong passwords in (#257) config * Update to ubuntu:18.04 and python3 packages and executables * Open config file as utf8 The default configuration file has utf8 characters, and python3 attempts to open the file as ASCII unless an alternate encoding is specified * Switch to the python3 uwsgi plugin * Update print and os.execv statements for python3 Python3 throws an exception when the first argument to os.execv is empty: ValueError: execv() arg 2 first element cannot be empty The module documentation suggests that the first element should be the name of the executed program: https://docs.python.org/3.7/library/os.html#os.execv * Map config.docker.yaml in to the container as a volume ./ops/entrypoint.py has the start of environment variable support to specify a configuration file, but it is incomplete until we update ./ops/daemons/uwsgi-docker.yaml or add environment support to oncall-notifier and oncall-scheduler. This commit allows users to map a specific configuration file in to their container and have it used by all oncall programs. * Convert line endings to match the rest of the project. * Add mysql port to docker configuration * Assume localhost mysql for default config.yaml * Update python-dev package and MySQL root password * Use password when configuring mysql The project has started using a password on the mysql instance. Once password auth is consistently working we can consider extracting the hardcoded password into an env file that is optionally randomly generated on initial startup. * Fix preview for round-robin (#269) * #275 fix for Python3 and Gunicorn load config * Fixed E303 flake8 * Change encoding & collation + test unicode name Co-authored-by: Daniel Wang <dwang159@gmail.com> Co-authored-by: ahm3djafri <42748963+ahm3djafri@users.noreply.github.com> Co-authored-by: TK <tkahnoski+github@gmail.com> Co-authored-by: Tim Freund <tim@freunds.net> Co-authored-by: Rafał Zawadzki <bluszcz@bluszcz.net>
2020-01-15 15:38:25 -08:00
if self.created_ids:
self.cursor.execute('DELETE FROM team WHERE id IN %s', (self.created_ids,))
2017-05-02 15:57:25 -07:00
self.connection.commit()
self.cursor.close()
self.connection.close()
factory = TeamFactory(request.function.prefix)
yield factory
factory.cleanup()
@pytest.fixture(scope="function")
def roster(request, team):
class RosterFactory(object):
def __init__(self, prefix):
self.prefix = prefix
self.created = []
def init(self, prefix):
self.prefix = prefix
def create(self, team_name):
roster_name = '_'.join([self.prefix, 'roster', str(len(self.created))])
re = requests.post(api_v0('teams/%s/rosters' % team_name),
json={'name': roster_name})
assert re.status_code in [201, 422]
self.created.append((roster_name, team_name))
return roster_name
def cleanup(self):
for roster_name, team_name in self.created:
requests.delete(api_v0('teams/%s/rosters/%s' % (team_name, roster_name)))
factory = RosterFactory(request.function.prefix)
yield factory
factory.cleanup()
@pytest.fixture(scope="function")
def schedule(roster, role):
class ScheduleFactory(object):
def __init__(self):
self.created = []
def create(self, team_name, roster_name, json):
re = requests.post(api_v0('teams/%s/rosters/%s/schedules' % (team_name, roster_name)), json=json)
assert re.status_code == 201
schedule_id = re.json()['id']
self.created.append(schedule_id)
return schedule_id
def cleanup(self):
for schedule_id in self.created:
requests.delete(api_v0('schedules/%d' % schedule_id))
factory = ScheduleFactory()
yield factory
factory.cleanup()
@pytest.fixture(scope="function")
def event(team, role):
class EventFactory(object):
def __init__(self, ):
self.created = []
self.teams = set()
def create(self, json):
re = requests.post(api_v0('events'), json=json)
assert re.status_code == 201
ev_id = re.json()
self.created.append(ev_id)
self.teams.add(json['team'])
return ev_id
def link(self, ids):
connection = db.connect()
cursor = connection.cursor()
link_id = uuid4().hex
cursor.execute('UPDATE `event` SET `link_id` = %s WHERE `id` IN %s', (link_id, ids))
connection.commit()
cursor.close()
connection.close()
return link_id
def cleanup(self):
for ev in self.created:
requests.delete(api_v0('events/%d' % ev))
for t in self.teams:
2017-11-03 10:57:51 -07:00
re = requests.get(api_v0('events?include_subscribed=false'), params={'team': t})
2017-05-02 15:57:25 -07:00
for ev in re.json():
requests.delete(api_v0('events/%d' % ev['id']))
factory = EventFactory()
yield factory
factory.cleanup()
@pytest.fixture(scope="function")
def role(request, roster):
class RoleFactory(object):
def __init__(self, prefix):
self.prefix = prefix
self.created = []
def create(self):
name = '_'.join([self.prefix, 'role', str(len(self.created))])
re = requests.post(api_v0('roles'), json={'name': name})
assert re.status_code in [201, 422]
self.created.append(name)
return name
def cleanup(self):
for role_name in self.created:
requests.delete(api_v0('roles/' + role_name))
factory = RoleFactory(request.function.prefix)
yield factory
factory.cleanup()
@pytest.fixture(scope="function")
def service(request):
class ServiceFactory(object):
def __init__(self, prefix):
self.prefix = prefix
self.created = []
self.mappings = []
def create(self):
name = '_'.join([self.prefix, 'service', str(len(self.created))])
re = requests.post(api_v0('services'), json={'name': name})
assert re.status_code in [201, 422]
self.created.append(name)
return name
def associate_team(self, service_name, team_name):
requests.post(api_v0('teams/%s/services' % team_name),
json={'name': service_name})
self.mappings.append((team_name, service_name))
def cleanup(self):
for team_name, service_name in self.mappings:
requests.delete(api_v0('teams/%s/services/%s' % (team_name, service_name)))
for service in self.created:
requests.delete(api_v0('services/' + service))
factory = ServiceFactory(request.function.prefix)
yield factory
factory.cleanup()