-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from observatorycontrolsystem/feature/setup-pro…
…ject Feature/setup project
- Loading branch information
Showing
8 changed files
with
164 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[run] | ||
source = schedule | ||
|
||
[report] | ||
omit = | ||
*/migrations/* | ||
*apps.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
language: python | ||
dist: xenial | ||
python: | ||
- '3.6' | ||
- '3.7' | ||
- '3.8' | ||
env: | ||
global: | ||
- DOCKER_USERNAME='ocstravisci' | ||
- secure: G7hWi4s6QYrhJYs0EyaeCzayrKcxAXVTJXWbBkPGgK6n8fQG2HL2NqLcX8sd7Tg73XhjsoYC5+iXb71MGh15yLDotTWfTdJ6zIWwOf5LGae6WphS1ZiAlgjAkqegvQNCvjRTrXJFSInLDkRUBhMTvHrVEk802p2Oqk1vuWedh5ubj4Rt71RMsLwR21uhI95Ra3JDIQIpL784lQAt8T5SrIXIsqaSwJ7Qf4oBRgHAgKgJw0CiuhN7Lc5POZ7Sh/8bK5IAQ+RstZ0aUvh8u3DbyVkiRjPmdb46w26M4SWyZyyYKHbRXDvu5niDVbfT08eBwIxTFkhQ4FFpyBphggrtgYPoUakw09inBc5EriIRpsZE26g8YjMx5CiTAonnKQRG97Uks/7jPIWg33NdQLESaljBDRZB1+AAeV87l3VCXXuEgXuehDcVbhWnXn+6ymLYG5shnZk+lCLPHe3nTFfx0ngMYLIShzcblM/s1rTtdWloFbytZLZZ8yMKOM347Ex9SmPLIsWZnFKiL/EdMNjcUotqiFGVxD3cchMr9QokNMRGJY/YM2bSdsKnXe/4Y1NDtKs++97LDR4JaGLG1B5WkAvwLGAC7oQ+6uqn6OpJk8tn6tB5breXWuYxDYs3xkh/T4gH7xFyTYV71OxRCVaeK2j74CYy1FqN5buR4auk9XU= | ||
services: | ||
- docker | ||
install: | ||
- pip install -U coverage coveralls | ||
- pip install -r requirements.txt | ||
script: coverage run manage.py test | ||
after_success: coveralls | ||
before_deploy: | ||
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin | ||
- export IMAGE=observatorycontrolsystem/downtime:${TRAVIS_TAG} | ||
- docker build -t $IMAGE . | ||
deploy: | ||
- provider: script | ||
script: docker push $IMAGE | ||
skip_cleanup: true | ||
on: | ||
tags: true |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,106 @@ | ||
# Downtime | ||
# Downtime Database | ||
|
||
This is the downtime database. It contains a schedule for planned downtime (right now just real time interface). | ||
[![Build Status](https://travis-ci.com/observatorycontrolsystem/downtime.svg?branch=master)](https://travis-ci.com/observatorycontrolsystem/downtime) | ||
[![Coverage Status](https://coveralls.io/repos/github/observatorycontrolsystem/downtime/badge.svg?branch=master)](https://coveralls.io/github/observatorycontrolsystem/downtime?branch=master) | ||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/7aa8dea066824e79bb7e681122598345)](https://www.codacy.com/gh/observatorycontrolsystem/downtime?utm_source=github.com&utm_medium=referral&utm_content=observatorycontrolsystem/downtime&utm_campaign=Badge_Grade) | ||
|
||
An entry in the database is returned in json and has the following format: | ||
An application with a database that stores periods of scheduled telescope downtime for an observatory with an | ||
API to access those downtimes. Within an observatory control system, downtimes can be used to block out time | ||
for things such as maintenance activites or education use on specific telescopes. | ||
|
||
{ | ||
"start": "2017-08-21T08:45:00Z", | ||
"end": "2017-08-21T09:45:00Z", | ||
"site": "coj", | ||
"observatory": "clma", | ||
"telescope": "0m4a", | ||
"reason": "RTI" | ||
} | ||
## Prerequisites | ||
|
||
The index url returns the entire schedule: | ||
- Python>=3.6 | ||
- (Optional) PostgreSQL | ||
|
||
[http://downtimedev.lco.gtn](http://downtimedev.lco.gtn) | ||
By default, the application uses a SQLite database. This is suitable for development, but PostgreSQL is | ||
recommended when running in production. | ||
|
||
## Example queries | ||
## Configuration | ||
|
||
This project is configured using environment variables. | ||
|
||
| Variable | Description | Default | | ||
| -------------------- | ---------------------------------------------------------------------------------- | ---------------------------- | | ||
| `SECRET_KEY` | Django Secret Key | `### CHANGE ME ###` | | ||
| `DB_ENGINE` | Database Engine, set to `django.db.backends.postgresql_psycopg2` to use PostgreSQL | `django.db.backends.sqlite3` | | ||
| `DB_NAME` | Database Name | `db.sqlite3` | | ||
| `DB_HOST` | Database Hostname, set this when using PostgreSQL | _empty string_ | | ||
| `DB_USER` | Database Username, set this when using PostgreSQL | _empty string_ | | ||
| `DB_PASS` | Database Password, set this when using PostgreSQL | _empty string_ | | ||
| `DB_PORT` | Database Port, set this when using PostgreSQL | `5432` | | ||
|
||
## Local Development | ||
|
||
### **Set up a virtual environment** | ||
|
||
Using a virtual environment is highly recommended. Run the following commands from the base of this project. `(env)` | ||
is used to denote commands that should be run using your virtual environment. | ||
|
||
python3 -m venv env | ||
source env/bin/activate | ||
(env) pip install -r requirements.txt | ||
|
||
### **Set up the database** | ||
|
||
You may use the default SQLite for development, or you can set up using PostgreSQL. If using SQLite, you can skip directly | ||
to running database migrations. If using PostgreSQL, the following command uses the [PostgreSQL Docker image](https://hub.docker.com/_/postgres) to | ||
create a PostgreSQL database. Make sure that the options that you use to set up your database correspond with your configured database settings. | ||
|
||
All filters can be chained (ANDed) together to narrow the results returned. | ||
docker run --name downtime-postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=downtime -v/var/lib/postgresql/data -p5432:5432 -d postgres:11.1 | ||
|
||
* Return the schedule past a specific date: | ||
Run database migrations to set up the tables in the database. | ||
|
||
[http://downtimedev.lco.gtn/?start__gte=2017-11-27%2014:45:00](http://downtimedev.lco.gtn/?start__gte=2017-11-27%2014:45:00) | ||
(env) python manage.py migrate | ||
|
||
* Return the schedule before a specific date: | ||
### Run the tests | ||
|
||
[http://downtimedev.lco.gtn/?end__lte=2017-08-24%2015:15:00](http://downtimedev.lco.gtn/?end__lte=2017-08-24%2015:15:00) | ||
(env) python manage.py test | ||
|
||
* Filter results by reason: | ||
### Run the application | ||
|
||
[http://downtimedev.lco.gtn/?reason=RTI](http://downtimedev.lco.gtn/?reason=RTI) | ||
(env) python manage.py runserver | ||
|
||
The application should now be accessible from <http://127.0.0.1:8000>! | ||
|
||
### Managing downtime entries | ||
|
||
Downtimes are added and deleted manually via the admin interface. In order to manage downtimes, you must | ||
first create a superuser. Run the following and fill out all of the questions: | ||
|
||
(env) python manage.py createsuperuser | ||
|
||
You can then log in as the newly created superuser at <http://127.0.0.1:8000/admin/> to manage downtimes. | ||
|
||
## Example queries | ||
|
||
A downtime entry in the database is returned in JSON and has the following format: | ||
|
||
{ | ||
"start": "2017-08-21T08:45:00Z", | ||
"end": "2017-08-21T09:45:00Z", | ||
"site": "coj", | ||
"observatory": "clma", | ||
"telescope": "0m4a", | ||
"reason": "Maintenance" | ||
} | ||
|
||
* Filter results by site, observatory and telescope: | ||
Return all downtimes | ||
|
||
[http://downtimedev.lco.gtn/?site=ogg&observatory=clma&telescope=0m4a](http://downtimedev.lco.gtn/?site=ogg&observatory=clma&telescope=0m4a) | ||
GET / | ||
|
||
It has no special needs for running or environmental variables, yet. | ||
Return the downtimes past a specific date: | ||
|
||
## Build | ||
GET /?start__gte=2017-11-27%2014:45:00 | ||
|
||
This project is built automatically by the [LCO Jenkins Server](http://jenkins.lco.gtn/). | ||
Please see the [Jenkinsfile](Jenkinsfile) for further details. | ||
Return the downtimes before a specific date: | ||
|
||
## Deployment | ||
GET /?end__lte=2017-08-24%2015:15:00 | ||
|
||
This project is deployed on the LCO Kubernetes Cluster. Please see the | ||
[LCO Helm Charts](https://github.com/LCOGT/helm-charts) repository for further | ||
information. | ||
Filter downtimes by reason: | ||
|
||
## Configuration / Environment Variables | ||
GET /?reason=Maintenance | ||
|
||
This project is configured using Environment Variables. | ||
Filter downtimes by site, observatory and telescope: | ||
|
||
| Environment Variable | Description | Default Value | | ||
| --- | --- | --- | | ||
| `SECRET_KEY` | The Django Secret Key | `""` | | ||
| `DB_HOST` | MySQL Database Hostname | `""` | | ||
| `DB_NAME` | MySQL Database Name | `""` | | ||
| `DB_USER` | MySQL Database Username | `""` | | ||
| `DB_PASS` | MySQL Database Password | `""` | | ||
GET /?site=ogg&observatory=clma&telescope=0m4a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,47 @@ | ||
from datetime import timedelta | ||
|
||
from django.test import TestCase | ||
from django.utils import timezone | ||
from django.urls import reverse | ||
from django.contrib.auth.models import User | ||
|
||
from schedule.models import Downtime | ||
|
||
|
||
class TestModelAdmin(TestCase): | ||
def setUp(self) -> None: | ||
super().setUp() | ||
self.admin_user = User.objects.create_superuser('admin', 'admin@example.com', 'admin') | ||
self.client.force_login(self.admin_user) | ||
|
||
@staticmethod | ||
def _get_post_data_for_new_downtime(start, end): | ||
return { | ||
'reason': 'Maintenance', | ||
'site': 'tst', | ||
'observatory': 'domx', | ||
'telescope': '1m0z', | ||
# POST data to the model admin add view expect that model fields that are | ||
# DateTimeFields are separated by date and time as follows | ||
'start_0': start.date(), | ||
'start_1': start.time(), | ||
'end_0': end.date(), | ||
'end_1': end.time(), | ||
} | ||
|
||
def test_add_downtime(self): | ||
start = timezone.now() - timedelta(days=2) | ||
end = start + timedelta(hours=1) | ||
data = self._get_post_data_for_new_downtime(start, end) | ||
self.assertEqual(Downtime.objects.count(), 0) | ||
self.client.post(reverse('admin:schedule_downtime_add'), data, follow=True) | ||
self.assertEqual(Downtime.objects.count(), 1) | ||
|
||
# Create your tests here. | ||
def test_downtime_with_end_before_start_not_allowed(self): | ||
start = timezone.now() - timedelta(days=2) | ||
end = start - timedelta(hours=1) | ||
data = self._get_post_data_for_new_downtime(start, end) | ||
self.assertEqual(Downtime.objects.count(), 0) | ||
response = self.client.post(reverse('admin:schedule_downtime_add'), data, follow=True) | ||
self.assertEqual(Downtime.objects.count(), 0) | ||
self.assertIn('Start time must come before end time', str(response.content)) |