1
0
mirror of https://github.com/linkedin/oncall.git synced 2025-11-30 23:44:59 +02:00
Files
oncall/e2e/test_schedules.py

168 lines
6.2 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
# -*- coding:utf-8 -*-
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
import urllib.parse
2017-05-02 15:57:25 -07:00
import requests
from testutils import prefix, api_v0
HOUR = 60 * 60
DAY = HOUR * 24
@prefix('test_v0_schedules')
def test_api_v0_schedules(team, roster, role):
tuesday9am = 2 * DAY + 9 * HOUR
tuesday9pm = tuesday9am + 12 * HOUR
wednesday9am = tuesday9pm + 12 * HOUR
wednesday9pm = wednesday9am + 12 * HOUR
team_name = team.create()
team_name_2 = team.create()
roster_name = roster.create(team_name)
roster_name_2 = roster.create(team_name_2)
role_name = role.create()
role_name_2 = role.create()
# test create schedule
events = [{'start': tuesday9am, 'duration': 12 * HOUR},
{'start': tuesday9pm, 'duration': 12 * HOUR},
{'start': wednesday9am, 'duration': 12 * HOUR},
{'start': wednesday9pm, 'duration': 12 * HOUR}]
re = requests.post(api_v0('teams/%s/rosters/%s/schedules' % (team_name, roster_name)),
json={
'role': role_name,
'events': events,
'advanced_mode': 1
})
assert re.status_code == 201
schedule_id = str(re.json()['id'])
# verify schedule created properly
re = requests.get(api_v0('teams/%s/rosters/%s/schedules' % (team_name, roster_name)))
assert re.status_code == 200
data = re.json()
assert len(data) == 1
schedule = data[0]
assert schedule['role'] == role_name
# check consecutive events have been merged
assert len(schedule['events']) == 1
assert schedule['events'][0]['start'] == tuesday9am
assert schedule['events'][0]['duration'] == 48 * HOUR
assert schedule['advanced_mode'] == 1
2017-09-05 13:48:57 -07:00
# test 'schedule' endpoint
re = requests.get(api_v0('schedules/%s' % (schedule_id)))
assert re.status_code == 200
assert re.json() == data[0]
2017-05-02 15:57:25 -07:00
updated_events = [{'start': 0, 'duration': 100}, {'start': 150, 'duration': 200}]
# verify schedule updates properly
re = requests.put(api_v0('schedules/' + schedule_id),
json={'role': role_name_2,
'team': team_name_2,
'roster': roster_name_2,
'auto_populate_threshold': 28,
'events': updated_events,
'advanced_mode': 1})
assert re.status_code == 200
re = requests.get(api_v0('teams/%s/rosters/%s/schedules' % (team_name_2, roster_name_2)))
assert re.status_code == 200
data = re.json()
assert len(data) == 1
schedule = data[0]
assert schedule['roster'] == roster_name_2
assert schedule['role'] == role_name_2
assert schedule['auto_populate_threshold'] == 28
assert schedule['events'] == updated_events
assert schedule['advanced_mode'] == 1
re = requests.put(api_v0('schedules/' + schedule_id), json={'team': team_name, 'roster': roster_name})
assert re.status_code == 200
# test delete schedule
re = requests.delete(api_v0('schedules/' + schedule_id))
assert re.status_code == 200
# verify schedule was deleted
re = requests.get(api_v0('teams/%s/rosters/%s/schedules' % (team_name_2, roster_name_2)))
assert re.status_code == 200
data = re.json()
assert data == []
@prefix('test_v0_advanced_schedule')
def test_api_v0_advanced_schedule(team, roster, role, schedule):
team_name = team.create()
roster_name = roster.create(team_name)
role_name = role.create()
schedule_id = schedule.create(team_name,
roster_name,
{'role': role_name,
'events': [{'start': 0, 'duration': 100},
{'start': 200, 'duration': 300}],
'advanced_mode': 1})
# check invalid schedule updates
re = requests.put(api_v0('schedules/%d' % schedule_id), json={'events': [{'start': 0, 'duration': 100},
{'start': 150, 'duration': 300}],
'advanced_mode': 0})
assert re.status_code == 400
re = requests.put(api_v0('schedules/%d' % schedule_id), json={'advanced_mode': 0})
assert re.status_code == 400
@prefix('test_v0_invalid_schedule_event')
def test_api_v0_invalid_schedule_event(team, roster, role, schedule):
team_name = team.create()
roster_name = roster.create(team_name)
role_name = role.create()
api_url = api_v0('teams/%s/rosters/%s/schedules' % (team_name, roster_name))
re = requests.post(api_url, json={
'role': role_name,
'events': [{'duration': 100},
{'start': 150, 'duration': 300}],
'advanced_mode': 1
})
assert re.status_code == 400
re = requests.post(api_url, json={
'role': role_name,
'events': [{'start': 150}],
'advanced_mode': 1
})
assert re.status_code == 400
re = requests.post(api_url, json={
'role': role_name,
'events': [{'start': 150, 'duration': 300}],
'advanced_mode': 0
})
assert re.status_code == 400
re = requests.post(api_url, json={
'role': role_name,
'events': 7 * [{'start': 150, 'duration': 300}],
'advanced_mode': 0
})
assert re.status_code == 400
@prefix('test_v0_schedules_spaces')
def test_api_v0_schedules_with_spaces_in_roster_name(team):
team_name = 'test_v0 spaces team foo'
roster_name = 'test_v0 spaces roster foo'
re = requests.post(api_v0('teams'), json={'name': team_name, 'scheduling_timezone': 'UTC'})
assert re.status_code == 201
team.mark_for_cleaning(team_name)
re = requests.post(api_v0('teams/%s/rosters' % team_name),
json={'name': roster_name})
assert re.status_code == 201
re = requests.get(api_v0('teams/%s/rosters/%s/schedules' %
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_name, urllib.parse.quote(roster_name, safe=''))))
2017-05-02 15:57:25 -07:00
assert re.status_code == 200