diff --git a/README.md b/README.md index 587885f..d67c8fa 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,11 @@ PROJECT STRUCTURE: -------------------------------------------------------------------------------------------- LAST VERSION -Date: 23/03/2018 +Date: 27/03/2018 By: E. Pallier -Version: 0.16.11 -- All unit tests now pass WITHOUT celery (./manage.py test or ./pyros.py test) : -it needed a bugfix on the json fixture !! (the pyrosuser quota was null : set it to 100) +Version: 0.16.12 +- BIG DEMO tests (simulator and simulator_development) pass WITH celery and PARTIALLY WITHOUT (./pyros.py simulator) +- All unit tests pass WITH or WITHOUT celery (./manage.py test or ./pyros.py test) - New global variable USE_CELERY (false by default) in pyros.settings - README file in each module (with version 0.1.0) - each agent (envmonitor, majordome, alert) can be started independently with a script (new script start_agent in each agent directory) diff --git a/pyros.py b/pyros.py index 813b4e4..6197240 100755 --- a/pyros.py +++ b/pyros.py @@ -645,6 +645,15 @@ class Pyros(AManager): def simulator_development(self): self.simulator(False) + ''' + (EP) utile pour le debug avec phpmyadmin pour remettre à zéro la bd pyros_test + delete from plan; + delete from album; + delete from schedule_has_sequences; + delete from schedule; + delete from sequence; + delete from request; + ''' # Simulation (by default, with ALL simulators and ALL celery workers) def simulator(self, TOTAL=True): @@ -660,6 +669,8 @@ class Pyros(AManager): else : self.execProcess("rm -f testdb.sqlite3") self.changeDirectory("..") if TOTAL: self.reset_database_sim() + # EP added: + if not TOTAL: self.reset_database_sim() # Actualise l’état de la DB en accord avec l’ensemble des modèles et des migrations actuels self.migrate() @@ -727,6 +738,17 @@ class Pyros(AManager): self.changeDirectory("..") ''' + # + # 4) (if not USE_CELERY) Start Agents + # + # TODO: + if TOTAL and not USE_CELERY : + # Start Environment Monitoring Agent + # Start Majordome Agent + # Start Alert Manager Agent + self.start_agents() + self.sleep(3) + # When simulators are finished: #self.kill_simulation() return 0 diff --git a/simulators/user/userSimulator.py b/simulators/user/userSimulator.py index f1898b1..b85ba37 100644 --- a/simulators/user/userSimulator.py +++ b/simulators/user/userSimulator.py @@ -47,7 +47,7 @@ class UserSimulator(): def sendRequest(self, file_name: str): files = {'request_file' : open(self.request_path + file_name, 'rb')} - print("Post request", self.url, "with args", files) + #print("Post request", self.url, "with args", files) # ex: Post request http://localhost:8000/routine_manager/import_request with args {'request_file': <_io.BufferedReader name='../resources/routine_request_01.xml'>} # This calls import_request() action from src/routine_manager/views.py r = self.client.post(self.url, files=files) diff --git a/src/common/models.py b/src/common/models.py index a5f9f5c..2d14b5a 100644 --- a/src/common/models.py +++ b/src/common/models.py @@ -554,6 +554,7 @@ class Sequence(models.Model): class ScheduleHasSequences(models.Model): + # (EP) TODO: C'est pas un pb d'utiliser 2 fois le meme nom "shs" pour 2 choses differentes ???!!! schedule = models.ForeignKey( 'Schedule', on_delete=models.CASCADE, related_name="shs") sequence = models.ForeignKey( diff --git a/src/majordome/tasks.py b/src/majordome/tasks.py index b769e32..97e82a9 100644 --- a/src/majordome/tasks.py +++ b/src/majordome/tasks.py @@ -177,6 +177,8 @@ class Majordome(Task): Function called by the main loop to handle the task event (check monitoring and alert_manager) ''' def handleTasks(self): + if not settings.USE_CELERY: return 0 + self.timers["tasks"] = self.tasks_timer if self.monitoring_task is None: try: @@ -306,7 +308,14 @@ class Majordome(Task): def handleNightEndTimer(self): self.timers["night_end"] = getNightEnd() if (self.isValidStatus(self.status_tel)): - observation_manager.tasks.night_calibrations.apply_async() + #observation_manager.tasks.night_calibrations.apply_async() + if settings.USE_CELERY: + print("MJ: call observation_manager WITH CELERY") + observation_manager.tasks.night_calibrations.apply_async() + else: + print("MJ: call observation_manager WITHOUT CELERY") + observation_manager.tasks.night_calibrations().run() + else: self.notifyTelescopeStatus("night_end") return (0) @@ -320,7 +329,14 @@ class Majordome(Task): self.dom.open() self.vis_camera.open_shutter() self.nir_camera.open_shutter() - scheduler.tasks.scheduling.apply_async((False, False)) + #scheduler.tasks.scheduling.apply_async((False, False)) + if settings.USE_CELERY: + print("MJ: call schedule WITH CELERY") + scheduler.tasks.scheduling.apply_async((False, False)) + else: + print("MJ: call schedule WITHOUT CELERY") + scheduler.tasks.scheduling().run((False, False)) + return (0) def notifyTelescopeStatus(self, timer_name): @@ -388,9 +404,22 @@ class Majordome(Task): def reset(self, type): if type == "WEATHER": self.dom.open() - scheduler.tasks.scheduling.delay((False, False)) + #scheduler.tasks.scheduling.delay((False, False)) + if settings.USE_CELERY: + print("MJ: call schedule WITH CELERY") + scheduler.tasks.scheduling.delay((False, False)) + else: + print("MJ: call schedule WITHOUT CELERY") + scheduler.tasks.scheduling().run((False, False)) + elif type == "INSIDE": - scheduler.tasks.scheduling.delay((False, False)) + #scheduler.tasks.scheduling.delay((False, False)) + if settings.USE_CELERY: + print("MJ: call schedule WITH CELERY") + scheduler.tasks.scheduling.delay((False, False)) + else: + print("MJ: call schedule WITHOUT CELERY") + scheduler.tasks.scheduling().run((False, False)) ''' Handle a new alarm (called by isInsideOk or isWeatherOk) @@ -485,8 +514,16 @@ class Majordome(Task): if sequence.albums.filter(detector__name="Cagire").exists(): if (self.isValidStatus(self.status_nir)): for plan in sequence.albums.get(detector__name="Cagire").plans.all(): - res = observation_manager.tasks.execute_plan_nir.apply_async( - (plan.id, float(self.getCountdown(shs)))) + #res = observation_manager.tasks.execute_plan_nir.apply_async((plan.id, float(self.getCountdown(shs)))) + if settings.USE_CELERY: + print("MJ: call observation_manager WITH CELERY") + res = observation_manager.tasks.execute_plan_nir.apply_async( + (plan.id, float(self.getCountdown(shs)))) + else: + print("MJ: call observation_manager WITHOUT CELERY") + res = observation_manager.tasks.execute_plan_nir().run( + (plan.id, float(self.getCountdown(shs)))) + # JB TODO : is it still usefull ? # TaskId.objects.create(task_id=res.id, task="execute_plan") plans_results.append(res) @@ -500,8 +537,14 @@ class Majordome(Task): if sequence.albums.filter(detector__name="Visible camera").exists(): if (self.isValidStatus(self.status_vis)): for plan in sequence.albums.get(detector__name="Visible camera").plans.all(): - res = observation_manager.tasks.execute_plan_vis.apply_async( - (plan.id, float(self.getCountdown(shs)))) + #res = observation_manager.tasks.execute_plan_vis.apply_async((plan.id, float(self.getCountdown(shs)))) + if settings.USE_CELERY: + print("MJ: call observation_manager WITH CELERY") + res = observation_manager.tasks.execute_plan_vis.apply_async((plan.id, float(self.getCountdown(shs)))) + else: + print("MJ: call observation_manager WITHOUT CELERY") + res = observation_manager.tasks.execute_plan_vis().run((plan.id, float(self.getCountdown(shs)))) + plans_results.append(res) else: self.notifyDeviceStatus("Camera visible", "Sequence execution", self.status_vis) @@ -583,7 +626,14 @@ class Majordome(Task): def systemPause(self, duration, cause: str): self.logDB("System in pause for " + str(duration)) time.sleep(duration) - scheduler.tasks.scheduling.apply_async(first_schedule=False, alert=False) + #scheduler.tasks.scheduling.apply_async(first_schedule=False, alert=False) + if settings.USE_CELERY: + print("MJ: call schedule WITH CELERY") + scheduler.tasks.scheduling.apply_async(first_schedule=False, alert=False) + else: + print("MJ: call schedule WITHOUT CELERY") + scheduler.tasks.scheduling().run(first_schedule=False, alert=False) + self.setTime() print("system has been paused. Cause : " + cause) return (0) diff --git a/src/misc/fixtures/initial_fixture_noTZ.json b/src/misc/fixtures/initial_fixture_noTZ.json new file mode 100644 index 0000000..8677edf --- /dev/null +++ b/src/misc/fixtures/initial_fixture_noTZ.json @@ -0,0 +1,497 @@ +[ +{ + "model": "common.country", + "pk": 1, + "fields": { + "name": "France", + "desc": "", + "quota": null + } +}, +{ + "model": "common.detector", + "pk": 1, + "fields": { + "telescope": 1, + "status": "", + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null, + "name": "Cagire", + "desc": "", + "created": "2016-05-13 11:49:49", + "updated": "2016-05-13 11:49:49", + "is_online": false, + "maintenance_date": null + } +}, +{ + "model": "common.detector", + "pk": 2, + "fields": { + "telescope": 1, + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null, + "name": "Visible camera", + "desc": "", + "created": "2016-05-13 11:50:17", + "updated": "2016-05-13 11:50:17", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.plc", + "pk": 1, + "fields": { + "last_update_status": null, + "name": "Plc", + "desc": "", + "created": "2016-05-13 11:50:14", + "updated": "2016-05-13 11:50:14", + "is_online": false, + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 1, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "First infrared filter", + "desc": "", + "created": "2016-05-13 11:49:56", + "updated": "2016-05-13 11:49:56", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 2, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "Second infrared filter", + "desc": "", + "created": "2016-05-13 11:50:07", + "updated": "2016-05-13 11:50:07", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 3, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "First visible filter", + "desc": "", + "created": "2016-05-13 11:50:02", + "updated": "2016-05-13 11:50:02", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 4, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "Second visible filter", + "desc": "", + "created": "2016-05-13 11:50:11", + "updated": "2016-05-13 11:50:11", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filterwheel", + "pk": 1, + "fields": { + "detector": 1, + "name": "Cagire FW", + "desc": "", + "created": "2016-06-28 13:28:28", + "updated": "2016-06-28 13:28:28", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filterwheel", + "pk": 2, + "fields": { + "detector": 2, + "name": "Visible Camera FW", + "desc": "", + "created": "2016-06-28 13:28:46", + "updated": "2016-06-28 13:28:46", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.scientificprogram", + "pk": 1, + "fields": { + "name": "GRB", + "desc": "", + "quota": 9999.0, + "priority": 0, + "pyros_users": [ + 5 + ] + } +}, +{ + "model": "common.strategyobs", + "pk": 1, + "fields": { + "name": "strat1", + "desc": "", + "xml_file": "strat1.xml", + "is_default": false + } +}, +{ + "model": "common.strategyobs", + "pk": 2, + "fields": { + "name": "strat2", + "desc": "", + "xml_file": "strat2.xml", + "is_default": false + } +}, +{ + "model": "common.strategyobs", + "pk": 3, + "fields": { + "name": "strat_unittest", + "desc": "", + "xml_file": "strat_unittest.xml", + "is_default": true + } +}, +{ + "model": "common.telescope", + "pk": 1, + "fields": { + "mount_type": "", + "diameter": null, + "status": "", + "latitude": null, + "longitude": null, + "sens": "", + "altitude": null, + "readout_time": null, + "slew_time": null, + "slew_dead": null, + "slew_rate_max": null, + "horizon_type": "", + "horizon_def": null, + "lim_dec_max": null, + "lim_dec_min": null, + "lim_ha_rise": null, + "lim_ha_set": null, + "address": "", + "night_elev_sun": null, + "mpc_code": "", + "name": "Telescope", + "desc": "", + "created": "2016-05-13 11:50:14", + "updated": "2016-05-13 11:50:14", + "is_online": false, + "maintenance_date": null + } +}, +{ + "model": "common.dome", + "pk": 1, + "fields": { + "name": "Dome", + "desc": "dome", + "created": "2016-05-13 11:50:14", + "updated": "2016-05-13 11:50:14", + "is_online": false, + "status": "", + "maintenance_date": null, + "open": false + } +}, +{ + "model": "common.userlevel", + "pk": 1, + "fields": { + "name": "Developer", + "desc": "", + "priority": 0, + "quota": 9999.0 + } +}, +{ + "model": "common.version", + "pk": 1, + "fields": { + "module_name": "Scheduler", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 2, + "fields": { + "module_name": "Dashboard", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 3, + "fields": { + "module_name": "Observation Manager", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 4, + "fields": { + "module_name": "Routine Manager", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 5, + "fields": { + "module_name": "Alert Manager", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 6, + "fields": { + "module_name": "Monitoring", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 7, + "fields": { + "module_name": "User Manager", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 8, + "fields": { + "module_name": "Analyzer", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 9, + "fields": { + "module_name": "Majordome", + "version": "0.1", + "created": "2016-06-23 14:04:48", + "updated": "2016-06-23 14:04:48" + } +}, +{ + "model": "common.version", + "pk": 10, + "fields": { + "module_name": "Majordome", + "version": "0.2", + "created": "2016-06-28 10:50:32", + "updated": "2016-06-28 10:50:32" + } +}, +{ + "model": "common.version", + "pk": 11, + "fields": { + "module_name": "Majordome", + "version": "0.1.4", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 12, + "fields": { + "module_name": "Alert Manager", + "version": "0.2.3", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 13, + "fields": { + "module_name": "Dashboard", + "version": "0.1.1", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 14, + "fields": { + "module_name": "Observation Manager", + "version": "0.1.3", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 15, + "fields": { + "module_name": "Routine Manager", + "version": "0.1.2", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 16, + "fields": { + "module_name": "Monitoring", + "version": "0.1.3", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 17, + "fields": { + "module_name": "Scheduler", + "version": "0.1.2", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 18, + "fields": { + "module_name": "User Manager", + "version": "0.1.1", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.version", + "pk": 19, + "fields": { + "module_name": "Analyzer", + "version": "0.1.2", + "created": "2016-07-20 13:44:29", + "updated": "2016-07-20 13:44:29" + } +}, +{ + "model": "common.pyrosuser", + "pk": 5, + "fields": { + "password": "pbkdf2_sha256$24000$HRial3QUfrlz$bVuEzQaXthOd9GZVXd2449LDEF8EMQure69nA/Hu7qQ=", + "last_login": "2016-08-10 15:16:42.327", + "is_superuser": true, + "username": "pyros", + "first_name": "", + "last_name": "", + "email": "admin@example.com", + "is_staff": true, + "is_active": true, + "date_joined": "2016-08-10 15:15:58.481", + "groups": [], + "user_permissions": [], + "country": 1, + "user_level": 1, + "desc": "", + "created": "2016-08-11 07:54:05.627", + "updated": "2016-08-11 07:54:05.627", + "tel": "", + "address": "", + "laboratory": "IRAP", + "last_connect": null, + "cur_connect": null, + "putvalid_beg": null, + "putvalid_end": null, + "acqvalid_beg": "", + "acqvalid_end": "", + "quota": 1000.0, + "quota_rea": null, + "u_priority": 1, + "p_priority": 1, + "dir_level": null, + "can_del_void_req": false + } +} +] diff --git a/src/misc/fixtures/make_current_is_TZ.sh b/src/misc/fixtures/make_current_is_TZ.sh new file mode 100755 index 0000000..750a7bc --- /dev/null +++ b/src/misc/fixtures/make_current_is_TZ.sh @@ -0,0 +1,13 @@ + +function make_change() { + for f in *_TZ.json ; do fname=$(basename $f _TZ.json) ; newname=${fname}.json ; echo "cp $f to $newname"; cp -p $f $newname ; done +} + + + +make_change +cd tests/ +make_change +ls -l ../ +ls -l + diff --git a/src/misc/fixtures/make_current_is_noTZ.sh b/src/misc/fixtures/make_current_is_noTZ.sh new file mode 100755 index 0000000..bf27608 --- /dev/null +++ b/src/misc/fixtures/make_current_is_noTZ.sh @@ -0,0 +1,13 @@ + +function make_change() { + for f in *_noTZ.json ; do fname=$(basename $f _noTZ.json) ; newname=${fname}.json ; echo "cp $f to $newname"; cp -p $f $newname ; done +} + + + +make_change +cd tests/ +make_change +ls -l ../ +ls -l + diff --git a/src/misc/fixtures/tests/alert_mgr_test_noTZ.json b/src/misc/fixtures/tests/alert_mgr_test_noTZ.json new file mode 100644 index 0000000..51a1c66 --- /dev/null +++ b/src/misc/fixtures/tests/alert_mgr_test_noTZ.json @@ -0,0 +1,311 @@ +[ +{ + "model": "common.country", + "pk": 1, + "fields": { + "name": "France", + "desc": "", + "quota": null + } +}, +{ + "model": "common.detector", + "pk": 1, + "fields": { + "telescope": 1, + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null, + "name": "Cagire", + "desc": "", + "created": "2016-05-13 11:49:49.663", + "updated": "2016-05-13 11:49:49.664", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.detector", + "pk": 2, + "fields": { + "telescope": 1, + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null, + "name": "Visible camera", + "desc": "", + "created": "2016-05-13 11:50:17.644", + "updated": "2016-05-13 11:50:17.644", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filterwheel", + "pk": 1, + "fields": { + "detector": 1, + "name": "Cagire FW", + "desc": "", + "created": "2016-06-28 13:28:28.298", + "updated": "2016-06-28 13:28:28.298", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filterwheel", + "pk": 2, + "fields": { + "detector": 2, + "name": "Visible Camera FW", + "desc": "", + "created": "2016-06-28 13:28:46.887", + "updated": "2016-06-28 13:28:46.887", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 1, + "fields": { + "filter_wheel": 1, + "category": "", + "transmission_curve_doc": "", + "name": "First infrared filter", + "desc": "", + "created": "2016-05-13 11:49:56.579", + "updated": "2016-05-13 11:49:56.579", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 2, + "fields": { + "filter_wheel": 1, + "category": "", + "transmission_curve_doc": "", + "name": "Second infrared filter", + "desc": "", + "created": "2016-05-13 11:50:07.592", + "updated": "2016-05-13 11:50:07.592", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 3, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "First visible filter", + "desc": "", + "created": "2016-05-13 11:50:02.012", + "updated": "2016-05-13 11:50:02.013", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 4, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "Second visible filter", + "desc": "", + "created": "2016-05-13 11:50:11.226", + "updated": "2016-05-13 11:50:11.226", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.scientificprogram", + "pk": 1, + "fields": { + "name": "GRB", + "desc": "", + "quota": 9999.0, + "priority": 0, + "pyros_users": [ + 1 + ] + } +}, +{ + "model": "common.strategyobs", + "pk": 1, + "fields": { + "name": "strat1", + "desc": "", + "xml_file": "strat1.xml" + } +}, +{ + "model": "common.strategyobs", + "pk": 2, + "fields": { + "name": "strat2", + "desc": "", + "xml_file": "strat2.xml" + } +}, +{ + "model": "common.telescope", + "pk": 1, + "fields": { + "mount_type": "", + "diameter": null, + "status": "", + "latitude": null, + "longitude": null, + "sens": "", + "altitude": null, + "readout_time": null, + "slew_time": null, + "slew_dead": null, + "slew_rate_max": null, + "horizon_type": "", + "horizon_def": null, + "lim_dec_max": null, + "lim_dec_min": null, + "lim_ha_rise": null, + "lim_ha_set": null, + "address": "", + "night_elev_sun": null, + "mpc_code": "", + "name": "Telescope", + "desc": "", + "created": "2016-05-13 11:50:14.326", + "updated": "2016-05-13 11:50:14.326", + "is_online": false, + "maintenance_date": null + } +}, +{ + "model": "common.userlevel", + "pk": 1, + "fields": { + "name": "Developer", + "desc": "", + "priority": 0, + "quota": 9999.0 + } +}, +{ + "model": "common.pyrosuser", + "pk": 3, + "fields": { + "country": 1, + "user_level": 1, + "desc": null, + "created": "2016-06-21 13:07:19.911", + "updated": "2016-06-21 13:07:19.911", + "tel": "test", + "address": "test", + "laboratory": "test", + "last_connect": null, + "cur_connect": null, + "putvalid_beg": null, + "putvalid_end": null, + "acqvalid_beg": null, + "acqvalid_end": null, + "quota": 100, + "quota_rea": null, + "u_priority": null, + "p_priority": null, + "dir_level": null, + "can_del_void_req": false, + "password": "pbkdf2_sha256$24000$bKJO902RCk0w$zxUz9uiSYG85ymuvl5rNLLqT/LZwrLwpVj5WfwwSyKE=", + "last_login": "2016-06-21 13:07:34.383", + "is_superuser": false, + "username": "test@test.test", + "first_name": "test", + "last_name": "test", + "email": "test@test.test", + "is_staff": false, + "is_active": true, + "date_joined": "2016-06-21 13:07:19.609", + "groups": [], + "user_permissions": [] + } +}, + +{ + "model": "common.alert", + "pk": 8, + "fields": { + "request": 65, + "strategyobs": 1, + "voevent_file": null, + "author": null, + "burst_jd": null, + "burst_ra": null, + "burst_dec": null, + "astro_coord_system": null, + "jd_send": null, + "jd_received": null, + "trig_id": 5, + "error_radius": null, + "defly_not_grb": false, + "editor": null + } +}, + + +{ + "model": "common.request", + "pk": 65, + "fields": { + "pyros_user": 3, + "scientific_program": 1, + "name": "Simulation_request", + "desc": null, + "created": "2016-06-21 12:51:24.293", + "updated": "2016-06-21 12:51:24.293", + "is_alert": true, + "target_type": null, + "status": null, + "autodeposit": false, + "checkpoint": null, + "flag": null, + "complete": true, + "submitted": true + } +} +] diff --git a/src/misc/fixtures/tests/common_test_noTZ.json b/src/misc/fixtures/tests/common_test_noTZ.json new file mode 100644 index 0000000..a18a232 --- /dev/null +++ b/src/misc/fixtures/tests/common_test_noTZ.json @@ -0,0 +1,268 @@ +[ +{ + "model": "common.country", + "pk": 1, + "fields": { + "name": "France", + "desc": "", + "quota": null + } +}, +{ + "model": "common.detector", + "pk": 1, + "fields": { + "telescope": 1, + "status": "", + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null, + "name": "Cagire", + "desc": "", + "created": "2016-05-13 11:49:49.663", + "updated": "2016-05-13 11:49:49.664", + "is_online": false, + "maintenance_date": null + } +}, +{ + "model": "common.detector", + "pk": 2, + "fields": { + "telescope": 1, + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null, + "name": "Visible camera", + "desc": "", + "created": "2016-05-13 11:50:17.644", + "updated": "2016-05-13 11:50:17.644", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filterwheel", + "pk": 1, + "fields": { + "name": "Cagire FW", + "desc": "", + "created": "2016-06-28 13:28:28.298", + "updated": "2016-06-28 13:28:28.298", + "is_online": false, + "status": "", + "maintenance_date": null, + "detector": 1 + } +}, +{ + "model": "common.filterwheel", + "pk": 2, + "fields": { + "detector": 2, + "name": "Visible Camera FW", + "desc": "", + "created": "2016-06-28 13:28:46.887", + "updated": "2016-06-28 13:28:46.887", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 1, + "fields": { + "filter_wheel": 1, + "category": "", + "transmission_curve_doc": "", + "name": "First infrared filter", + "desc": "", + "created": "2016-05-13 11:49:56.579", + "updated": "2016-05-13 11:49:56.579", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 2, + "fields": { + "filter_wheel": 1, + "category": "", + "transmission_curve_doc": "", + "name": "Second infrared filter", + "desc": "", + "created": "2016-05-13 11:50:07.592", + "updated": "2016-05-13 11:50:07.592", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 3, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "First visible filter", + "desc": "", + "created": "2016-05-13 11:50:02.012", + "updated": "2016-05-13 11:50:02.013", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 4, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "Second visible filter", + "desc": "", + "created": "2016-05-13 11:50:11.226", + "updated": "2016-05-13 11:50:11.226", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.scientificprogram", + "pk": 1, + "fields": { + "name": "GRB", + "desc": "", + "quota": 9999.0, + "priority": 0, + "pyros_users": [ + 1 + ] + } +}, +{ + "model": "common.strategyobs", + "pk": 1, + "fields": { + "name": "strat1", + "desc": "", + "xml_file": "strat1.xml" + } +}, +{ + "model": "common.strategyobs", + "pk": 2, + "fields": { + "name": "strat2", + "desc": "", + "xml_file": "strat2.xml" + } +}, +{ + "model": "common.telescope", + "pk": 1, + "fields": { + "mount_type": "", + "diameter": null, + "status": "", + "latitude": null, + "longitude": null, + "sens": "", + "altitude": null, + "readout_time": null, + "slew_time": null, + "slew_dead": null, + "slew_rate_max": null, + "horizon_type": "", + "horizon_def": null, + "lim_dec_max": null, + "lim_dec_min": null, + "lim_ha_rise": null, + "lim_ha_set": null, + "address": "", + "night_elev_sun": null, + "mpc_code": "", + "name": "Telescope", + "desc": "", + "created": "2016-05-13 11:50:14.326", + "updated": "2016-05-13 11:50:14.326", + "is_online": false, + "maintenance_date": null + } +}, +{ + "model": "common.userlevel", + "pk": 1, + "fields": { + "name": "Developer", + "desc": "", + "priority": 0, + "quota": 9999.0 + } +}, +{ + "model": "common.pyrosuser", + "pk": 1, + "fields": { + "password": "pbkdf2_sha256$24000$NC9UO4LPGvDN$+pkRcZUbmV3HEtbrhBdDCSPnAsDVValrbwLt7cXqrJE=", + "last_login": "2016-06-03 09:27:53.245", + "is_superuser": true, + "username": "haribo", + "first_name": "", + "last_name": "", + "email": "", + "is_staff": true, + "is_active": true, + "date_joined": "2016-05-02 14:02:36.495", + "groups": [], + "user_permissions": [], + "country": 1, + "user_level": 1, + "desc": "", + "created": "2016-06-03 09:29:15.450", + "updated": "2016-06-03 09:29:15.450", + "tel": "", + "address": "", + "laboratory": "", + "last_connect": null, + "cur_connect": null, + "putvalid_beg": null, + "putvalid_end": null, + "acqvalid_beg": "", + "acqvalid_end": "", + "quota": 9999.0, + "quota_rea": 9999.0, + "u_priority": null, + "p_priority": null, + "dir_level": null, + "can_del_void_req": false + } +} +] diff --git a/src/misc/fixtures/tests/routine_mgr_test_noTZ.json b/src/misc/fixtures/tests/routine_mgr_test_noTZ.json new file mode 100644 index 0000000..a9eff1a --- /dev/null +++ b/src/misc/fixtures/tests/routine_mgr_test_noTZ.json @@ -0,0 +1,349 @@ +[ +{ + "model": "common.country", + "pk": 1, + "fields": { + "name": "France", + "desc": "", + "quota": null + } +}, +{ + "model": "common.detector", + "pk": 1, + "fields": { + "name": "Cagire", + "desc": "", + "created": "2016-05-13 11:49:49.663", + "updated": "2016-05-13 11:49:49.664", + "is_online": false, + "maintenance_date": null, + "telescope": 1, + "status": "", + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null + } +}, +{ + "model": "common.detector", + "pk": 2, + "fields": { + "name": "Visible camera", + "desc": "", + "created": "2016-05-13 11:50:17.644", + "updated": "2016-05-13 11:50:17.644", + "is_online": false, + "maintenance_date": null, + "telescope": 1, + "status": "", + "nb_photo_x": null, + "nb_photo_y": null, + "photo_size_x": null, + "photo_size_y": null, + "has_shutter": false, + "equivalent_foc_len": "", + "acq_start": null, + "acq_stop": null, + "check_temp": null, + "gain": null, + "readout_noise": null, + "readout_time": null, + "idcam_readout_mode": null + } +}, +{ + "model": "common.filterwheel", + "pk": 1, + "fields": { + "name": "Cagire FW", + "desc": "", + "created": "2016-06-28 13:28:28.298", + "updated": "2016-06-28 13:28:28.298", + "is_online": false, + "status": "", + "maintenance_date": null, + "detector": 1 + } +}, +{ + "model": "common.filterwheel", + "pk": 2, + "fields": { + "name": "Visible Camera FW", + "desc": "", + "created": "2016-06-28 13:28:46.887", + "updated": "2016-06-28 13:28:46.887", + "is_online": false, + "status": "", + "maintenance_date": null, + "detector": 2 + } +}, +{ + "model": "common.filter", + "pk": 1, + "fields": { + "name": "First infrared filter", + "desc": "", + "created": "2016-05-13 11:49:56.579", + "updated": "2016-05-13 11:49:56.579", + "is_online": false, + "status": "", + "maintenance_date": null, + "filter_wheel": 1, + "category": "", + "transmission_curve_doc": "" + } +}, +{ + "model": "common.filter", + "pk": 2, + "fields": { + "filter_wheel": 1, + "category": "", + "transmission_curve_doc": "", + "name": "Second infrared filter", + "desc": "", + "created": "2016-05-13 11:50:07.592", + "updated": "2016-05-13 11:50:07.592", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 3, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "First visible filter", + "desc": "", + "created": "2016-05-13 11:50:02.012", + "updated": "2016-05-13 11:50:02.013", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.filter", + "pk": 4, + "fields": { + "filter_wheel": 2, + "category": "", + "transmission_curve_doc": "", + "name": "Second visible filter", + "desc": "", + "created": "2016-05-13 11:50:11.226", + "updated": "2016-05-13 11:50:11.226", + "is_online": false, + "status": "", + "maintenance_date": null + } +}, +{ + "model": "common.scientificprogram", + "pk": 1, + "fields": { + "name": "GRB", + "desc": "", + "quota": 9999.0, + "priority": 0, + "pyros_users": [ + 1 + ] + } +}, +{ + "model": "common.strategyobs", + "pk": 1, + "fields": { + "name": "strat1", + "desc": "", + "xml_file": "strat1.xml" + } +}, +{ + "model": "common.strategyobs", + "pk": 2, + "fields": { + "name": "strat2", + "desc": "", + "xml_file": "strat2.xml" + } +}, +{ + "model": "common.telescope", + "pk": 1, + "fields": { + "name": "Telescope", + "desc": "", + "created": "2016-05-13 11:50:14.326", + "updated": "2016-05-13 11:50:14.326", + "is_online": false, + "maintenance_date": null, + "mount_type": "", + "diameter": null, + "status": "", + "latitude": null, + "longitude": null, + "sens": "", + "altitude": null, + "readout_time": null, + "slew_time": null, + "slew_dead": null, + "slew_rate_max": null, + "horizon_type": "", + "horizon_def": null, + "lim_dec_max": null, + "lim_dec_min": null, + "lim_ha_rise": null, + "lim_ha_set": null, + "address": "", + "night_elev_sun": null, + "mpc_code": "" + } +}, +{ + "model": "common.userlevel", + "pk": 1, + "fields": { + "name": "Developer", + "desc": "", + "priority": 0, + "quota": 9999.0 + } +}, +{ + "model": "common.pyrosuser", + "pk": 3, + "fields": { + "password": "pbkdf2_sha256$24000$bKJO902RCk0w$zxUz9uiSYG85ymuvl5rNLLqT/LZwrLwpVj5WfwwSyKE=", + "last_login": "2016-06-21 13:07:34.383", + "is_superuser": false, + "username": "test@test.test", + "first_name": "test", + "last_name": "test", + "email": "test@test.test", + "is_staff": false, + "is_active": true, + "date_joined": "2016-06-21 13:07:19.609", + "groups": [], + "user_permissions": [], + "country": 1, + "user_level": 1, + "desc": null, + "created": "2016-06-21 13:07:19.911", + "updated": "2016-06-21 13:07:19.911", + "tel": "test", + "address": "test", + "laboratory": "test", + "last_connect": null, + "cur_connect": null, + "putvalid_beg": null, + "putvalid_end": null, + "acqvalid_beg": null, + "acqvalid_end": null, + "quota": null, + "quota_rea": null, + "u_priority": null, + "p_priority": null, + "dir_level": null, + "can_del_void_req": false + } +},{ + "model": "common.request", + "pk": 66, + "fields": { + "pyros_user": 3, + "scientific_program": 1, + "name": "Simulation_request_strat2", + "desc": null, + "created": "2016-06-21 13:42:04.493", + "updated": "2016-06-22 12:34:09.401", + "is_alert": true, + "target_type": "dqsd", + "status": null, + "autodeposit": false, + "checkpoint": null, + "flag": null, + "complete": true, + "submitted": false + } +}, +{ + "model": "common.sequence", + "pk": 53, + "fields": { + "request": 66, + "name": "Simulation_request_strat2_0", + "desc": null, + "created": "2016-06-21 13:42:04.587", + "updated": "2016-06-22 12:32:16.892", + "is_alert": false, + "status": "CPL", + "target_coords": "sdfghj", + "with_drift": false, + "priority": 0, + "analysis_method": null, + "moon_min": null, + "alt_min": null, + "type": null, + "img_current": null, + "img_total": null, + "not_obs": false, + "obsolete": false, + "processing": false, + "flag": null, + "jd1": "0E-8", + "jd2": "9000000.00000000", + "t_prefered": "-1.00000000", + "duration": "0.00023148", + "overhead": "0E-8" + } +}, +{ + "model": "common.album", + "pk": 55, + "fields": { + "sequence": 53, + "detector": 2, + "name": "Simulation_request_strat2_01", + "desc": null, + "created": "2016-06-21 13:42:04.874", + "updated": "2016-06-22 12:32:16.787", + "complete": true + } +}, +{ + "model": "common.plan", + "pk": 58, + "fields": { + "album": 55, + "filter": 3, + "name": "Simulation_request_strat2_010", + "desc": null, + "created": "2016-06-21 13:42:05.309", + "updated": "2016-06-22 12:32:16.690", + "duration": 0.0002314814814814815, + "position": null, + "exposure_time": null, + "nb_images": 1, + "dithering": false, + "complete": true + } +} +] diff --git a/src/pyros/settings.py b/src/pyros/settings.py index d9f679f..ed07989 100644 --- a/src/pyros/settings.py +++ b/src/pyros/settings.py @@ -206,7 +206,7 @@ USE_L10N = True # TODO: fix this # Necessary for ENV monitoring : USE_TZ = False -# Still necessary for "pyros.py simulator" (because of some fixtures that still use timezone-aware datetimes) +#USE_TZ = True #if USE_CELERY: USE_TZ = True # To find the media files {{ MEDIA_URL }} diff --git a/src/pyros/test_settings.py b/src/pyros/test_settings.py deleted file mode 100644 index f80e37a..0000000 --- a/src/pyros/test_settings.py +++ /dev/null @@ -1,288 +0,0 @@ -""" OBSOLETE FILE """ -""" -Django settings for pyros project. - -Generated by 'django-admin startproject' using Django 1.9.4. - -For more information on this file, see -https://docs.djangoproject.com/en/1.9/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.9/ref/settings/ -""" - -# Dictionary containing all the versions for the different modules -# IMPORTANT : I must be updated at every commit ! - -MODULES_VERSIONS = { - "Alert Manager" : "0.2.4", - "Analyzer" : "0.1.2", - "Dashboard" : "0.1.1", - "Majordome" : "0.1.4", - "Monitoring" : "0.1.3", - "Observation Manager" : "0.1.3", - "Routine Manager" : "0.1.2", - "Scheduler" : "0.1.2", - "User Manager" : "0.1.1", - "Device" : "0.1.1" -} - -# Set MYSQL to False if you want to use SQLITE -# This line MUST NOT be changed at all except from changing True/False -# (or install_requirements script will become invalid) -MYSQL = True - -# YOU MUST CHANGE THIS VALUE IN PYROSRUN.SH TOO -TEST_PORT = 8001 -# YOU MUST CHANGE THIS VALUE IN PYROSRUN.SH TOO - - -import os - -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '0*@w)$rq4x1c2w!c#gn58*$*u$w=s8uw2zpr_c3nj*u%qlxc23' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = ['localhost'] - - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - - # for using "./manage.py graph_models" with graphviz: - # (https://projects.irap.omp.eu/projects/pyros/wiki/Project_Development#django-extensions-and-graphviz-useful-for-generating-an-image-of-all-the-models-and-their-relationships) - 'django_extensions', - 'test_without_migrations', - 'bootstrap3', - 'dashboard', - 'scheduler', - 'common', - 'alert_manager', - 'analyzer', - 'majordome', - 'monitoring', - 'observation_manager', - 'routine_manager', - 'user_manager', - 'devices' -] - -MIDDLEWARE_CLASSES = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - -ROOT_URLCONF = 'pyros.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': ['misc/templates'], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'pyros.wsgi.application' - -FIXTURE_DIRS = ( - 'misc/fixtures/', -) - -LOGIN_URL = "/" - -# Database -# https://docs.djangoproject.com/en/1.9/ref/settings/#databases - -# EP modif - -CELERY_TEST = False - -if not CELERY_TEST: - if not MYSQL: - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } - } - else: - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'test_pyros', - 'USER': 'pyros', - 'PASSWORD': 'DjangoPyros', - } - } -else: - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'testdb.sqlite3'), - 'TEST': { - 'NAME': os.path.join(BASE_DIR, 'testdb.sqlite3'), - }, - } - } - - -# Password validation -# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/1.9/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - - -# To find the media files {{ MEDIA_URL }} -MEDIA_URL = '/public/static/media/' - - -# To find the static files in the app/static/ap/... folders -STATIC_URL = '/public/static/' - -# To find the static files in src/static/. Any local directory can be added to this list. -STATICFILES_DIRS = ( - os.path.join(BASE_DIR, "misc", "static"), - ) - -# Used for deployment (DEBUG = False). Need to run "python manage.py collectstatic" to fill it. -STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'public', 'static') - - -# EP added -if not DEBUG: - ''' - CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - 'LOCATION': '127.0.0.1:11211', - } - } - ''' - CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/var/tmp/django_cache', - } - } - -else: - CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - } - } - -# from django.core.cache import cache -# cache.clear() - -# CELERY CONFIG - -# CELERY_RESULT_BACKEND = 'rpc://' -CELERY_RESULT_BACKEND = 'amqp' - -CELERY_ACCEPT_CONTENT = ['json'] -CELERY_TASK_SERIALIZER = 'json' -CELERY_RESULT_SERIALIZER = 'json' - -CELERY_IMPORTS = ( - "alert_manager.tasks", - "analyzer.tasks", - "majordome.tasks", - "monitoring.tasks", - "observation_manager.tasks", - "scheduler.tasks", -) - -# This config allows only 1 process / queue. We replace it by the -c option at celery workers creation. -# CELERYD_CONCURRENCY = 1 - -''' Following config is needed for manual purge ''' -CELERY_ACKS_LATE = False -CELERYD_PREFETCH_MULTIPLIER = 1 - -CELERY_QUEUES = { - "alert_listener_q": {"exchange": "alert_listener_q", "routing_key": "alert_listener_q"}, - "analysis_q": {"exchange": "analysis_q", "routing_key": "analysis_q"}, - "system_status_q": {"exchange": "system_status_q", "routing_key": "system_status_q"}, - "change_obs_conditions_q": {"exchange": "change_obs_conditions_q", "routing_key": "change_obs_conditions_q"}, - "monitoring_q": {"exchange": "monitoring_q", "routing_key": "monitoring_q"}, - "scheduling_q": {"exchange": "scheduling_q", "routing_key": "scheduling_q"}, - "execute_sequence_q": {"exchange": "execute_sequence_q", "routing_key": "execute_sequence_q"}, - "execute_plan_vis_q": {"exchange": "execute_plan_vis_q", "routing_key": "execute_plan_vis_q"}, - "execute_plan_nir_q": {"exchange": "execute_plan_nir_q", "routing_key": "execute_plan_nir_q"}, - "create_calibrations_q": {"exchange": "create_calibrations_q", "routing_key": "create_calibrations_q"}, -} - -CELERY_ROUTES = { - "alert_manager.tasks.alert_listener": {"queue": "alert_listener_q"}, - "analyzer.tasks.analysis": {"queue": "analysis_q"}, - "majordome.tasks.execute_sequence": {"queue": "execute_sequence_q"}, - "majordome.tasks.system_pause": {"queue": "system_status_q"}, - "majordome.tasks.system_restart": {"queue": "system_status_q"}, - "majordome.tasks.change_obs_conditions": {"queue": "change_obs_conditions_q"}, - "monitoring.tasks.monitoring": {"queue": "monitoring_q"}, - "observation_manager.tasks.execute_plan_vis": {"queue": "execute_plan_vis_q"}, - "observation_manager.tasks.execute_plan_nir": {"queue": "execute_plan_nir_q"}, - "observation_manager.tasks.create_calibrations": {"queue": "create_calibrations_q"}, - "scheduler.tasks.scheduling": {"queue": "scheduling_q"}, -} - -''' Removes pickle warning ''' -CELERY_ACCEPT_CONTENT = ['pickle', 'json', 'msgpack', 'yaml'] diff --git a/src/pyros/test_settings_NOTUSED.py b/src/pyros/test_settings_NOTUSED.py new file mode 100644 index 0000000..0a94e17 --- /dev/null +++ b/src/pyros/test_settings_NOTUSED.py @@ -0,0 +1,290 @@ +""" OBSOLETE FILE """ +""" +Django settings for pyros project. + +Generated by 'django-admin startproject' using Django 1.9.4. + +For more information on this file, see +https://docs.djangoproject.com/en/1.9/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.9/ref/settings/ +""" + +# Dictionary containing all the versions for the different modules +# IMPORTANT : I must be updated at every commit ! + +MODULES_VERSIONS = { + "Alert Manager" : "0.2.4", + "Analyzer" : "0.1.2", + "Dashboard" : "0.1.1", + "Majordome" : "0.1.4", + "Monitoring" : "0.1.3", + "Observation Manager" : "0.1.3", + "Routine Manager" : "0.1.2", + "Scheduler" : "0.1.2", + "User Manager" : "0.1.1", + "Device" : "0.1.1" +} + +# Set MYSQL to False if you want to use SQLITE +# This line MUST NOT be changed at all except from changing True/False +# (or install_requirements script will become invalid) +MYSQL = True + +# YOU MUST CHANGE THIS VALUE IN PYROSRUN.SH TOO +TEST_PORT = 8001 +# YOU MUST CHANGE THIS VALUE IN PYROSRUN.SH TOO + + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '0*@w)$rq4x1c2w!c#gn58*$*u$w=s8uw2zpr_c3nj*u%qlxc23' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ['localhost'] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + # for using "./manage.py graph_models" with graphviz: + # (https://projects.irap.omp.eu/projects/pyros/wiki/Project_Development#django-extensions-and-graphviz-useful-for-generating-an-image-of-all-the-models-and-their-relationships) + 'django_extensions', + 'test_without_migrations', + 'bootstrap3', + 'dashboard', + 'scheduler', + 'common', + 'alert_manager', + 'analyzer', + 'majordome', + 'monitoring', + 'observation_manager', + 'routine_manager', + 'user_manager', + 'devices' +] + +MIDDLEWARE_CLASSES = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'pyros.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': ['misc/templates'], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'pyros.wsgi.application' + +FIXTURE_DIRS = ( + 'misc/fixtures/', +) + +LOGIN_URL = "/" + +# Database +# https://docs.djangoproject.com/en/1.9/ref/settings/#databases + +# EP modif + +CELERY_TEST = False + +if not CELERY_TEST: + if not MYSQL: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } + } + else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'test_pyros', + 'USER': 'pyros', + 'PASSWORD': 'DjangoPyros', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'testdb.sqlite3'), + 'TEST': { + 'NAME': os.path.join(BASE_DIR, 'testdb.sqlite3'), + }, + } + } + + +# Password validation +# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.9/topics/i18n/ + +#LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'fr-FR' + +#TIME_ZONE = 'UTC' +TIME_ZONE = 'Europe/Paris' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# To find the media files {{ MEDIA_URL }} +MEDIA_URL = '/public/static/media/' + + +# To find the static files in the app/static/ap/... folders +STATIC_URL = '/public/static/' + +# To find the static files in src/static/. Any local directory can be added to this list. +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, "misc", "static"), + ) + +# Used for deployment (DEBUG = False). Need to run "python manage.py collectstatic" to fill it. +STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'public', 'static') + + +# EP added +if not DEBUG: + ''' + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': '127.0.0.1:11211', + } + } + ''' + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + 'LOCATION': '/var/tmp/django_cache', + } + } + +else: + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', + } + } + +# from django.core.cache import cache +# cache.clear() + +# CELERY CONFIG + +# CELERY_RESULT_BACKEND = 'rpc://' +CELERY_RESULT_BACKEND = 'amqp' + +CELERY_ACCEPT_CONTENT = ['json'] +CELERY_TASK_SERIALIZER = 'json' +CELERY_RESULT_SERIALIZER = 'json' + +CELERY_IMPORTS = ( + "alert_manager.tasks", + "analyzer.tasks", + "majordome.tasks", + "monitoring.tasks", + "observation_manager.tasks", + "scheduler.tasks", +) + +# This config allows only 1 process / queue. We replace it by the -c option at celery workers creation. +# CELERYD_CONCURRENCY = 1 + +''' Following config is needed for manual purge ''' +CELERY_ACKS_LATE = False +CELERYD_PREFETCH_MULTIPLIER = 1 + +CELERY_QUEUES = { + "alert_listener_q": {"exchange": "alert_listener_q", "routing_key": "alert_listener_q"}, + "analysis_q": {"exchange": "analysis_q", "routing_key": "analysis_q"}, + "system_status_q": {"exchange": "system_status_q", "routing_key": "system_status_q"}, + "change_obs_conditions_q": {"exchange": "change_obs_conditions_q", "routing_key": "change_obs_conditions_q"}, + "monitoring_q": {"exchange": "monitoring_q", "routing_key": "monitoring_q"}, + "scheduling_q": {"exchange": "scheduling_q", "routing_key": "scheduling_q"}, + "execute_sequence_q": {"exchange": "execute_sequence_q", "routing_key": "execute_sequence_q"}, + "execute_plan_vis_q": {"exchange": "execute_plan_vis_q", "routing_key": "execute_plan_vis_q"}, + "execute_plan_nir_q": {"exchange": "execute_plan_nir_q", "routing_key": "execute_plan_nir_q"}, + "create_calibrations_q": {"exchange": "create_calibrations_q", "routing_key": "create_calibrations_q"}, +} + +CELERY_ROUTES = { + "alert_manager.tasks.alert_listener": {"queue": "alert_listener_q"}, + "analyzer.tasks.analysis": {"queue": "analysis_q"}, + "majordome.tasks.execute_sequence": {"queue": "execute_sequence_q"}, + "majordome.tasks.system_pause": {"queue": "system_status_q"}, + "majordome.tasks.system_restart": {"queue": "system_status_q"}, + "majordome.tasks.change_obs_conditions": {"queue": "change_obs_conditions_q"}, + "monitoring.tasks.monitoring": {"queue": "monitoring_q"}, + "observation_manager.tasks.execute_plan_vis": {"queue": "execute_plan_vis_q"}, + "observation_manager.tasks.execute_plan_nir": {"queue": "execute_plan_nir_q"}, + "observation_manager.tasks.create_calibrations": {"queue": "create_calibrations_q"}, + "scheduler.tasks.scheduling": {"queue": "scheduling_q"}, +} + +''' Removes pickle warning ''' +CELERY_ACCEPT_CONTENT = ['pickle', 'json', 'msgpack', 'yaml'] diff --git a/src/routine_manager/RequestSerializer.py b/src/routine_manager/RequestSerializer.py index c0b59f5..5235afa 100644 --- a/src/routine_manager/RequestSerializer.py +++ b/src/routine_manager/RequestSerializer.py @@ -10,8 +10,8 @@ from jdcal import gcal2jd, jd2gcal import time import datetime import utils.Logger as L -#import scheduler.tasks as task -import scheduler.tasks +import scheduler.tasks as task +#import scheduler.tasks log = L.setupLogger("RequestSerializerLogger", "RequestSerializer") def prettify(elem): @@ -71,6 +71,7 @@ class RequestSerializer(): return "Invalid file : " + str(E) self.pyros_user = pyros_user + print("RS: pyros user is ", pyros_user) self.request = None """ self.sequences will be a [(seq, album_list), ...], and same thing for album """ @@ -86,8 +87,15 @@ class RequestSerializer(): self.request.save() for sequence, albums in self.sequences: if self.relative: + # 86400 = nb seconds in 24 h sequence.jd1 = (time.time() + float(sequence.jd1)) / 86400 + TIMESTAMP_JD sequence.jd2 = (time.time() + float(sequence.jd2)) / 86400 + TIMESTAMP_JD + #print("********* jd1,jd2 ", sequence.jd1, sequence.jd2) + + # EP avirer + #sequence.jd1 += float( (1/24)*2 ) + #sequence.jd2 += float( (1/24)*2 ) + sequence.request = self.request sequence.save() for album, plans in albums: @@ -101,10 +109,12 @@ class RequestSerializer(): #ret = task.scheduling.delay(first_schedule=False, alert=False) if settings.USE_CELERY: print("RS: schedule WITH CELERY") - scheduler.tasks.scheduling.delay(first_schedule=False, alert=False) + #ret = scheduler.tasks.scheduling.delay(first_schedule=False, alert=False) + ret = task.scheduling.delay(first_schedule=False, alert=False) else: print("RS: schedule WITHOUT CELERY") - scheduler.tasks.scheduling().run(first_schedule=False, alert=False) + #ret = scheduler.tasks.scheduling().run(first_schedule=False, alert=False) + ret = task.scheduling().run(first_schedule=False, alert=False) return "" diff --git a/src/routine_manager/views.py b/src/routine_manager/views.py index bf72dad..16e2347 100644 --- a/src/routine_manager/views.py +++ b/src/routine_manager/views.py @@ -48,7 +48,7 @@ def requests_list(request, status=0, message=""): requests = [] for req in requests_objs: - print("- REQ/views: requete", req) + #print("- REQ/views: requete", req) sequences = req.sequences nb_executed = sequences.filter(status=Sequence.EXECUTED).count nb_cancelled = sequences.filter(Q(status=Sequence.INVALID) | Q(status=Sequence.CANCELLED) @@ -443,7 +443,7 @@ def submit_request(request, req_id, redir): scheduler.tasks.scheduling.delay(first_schedule=True, alert=False) else: print("WITHOUT CELERY") - scheduler.tasks.scheduling().delay(first_schedule=True, alert=False) + scheduler.tasks.scheduling().run(first_schedule=True, alert=False) message = "The request was submitted" if redir == "action_request": @@ -464,7 +464,7 @@ def unsubmit_request(request, req_id): # TODO: uncomment pour la production # if req.sequences.filter(Q(status=Sequence.EXECUTED) | Q(status=Sequence.EXECUTING)).exists(): -# message = "You can't unsubmit an request with executed sequences" +# message = "You can't unsubmit a request with executed sequences" # return redirect(action_request, req_id=req_id, action="view", status=-1, message=message) req.submitted = False diff --git a/src/scheduler/Scheduler.py b/src/scheduler/Scheduler.py index c493546..55a784e 100644 --- a/src/scheduler/Scheduler.py +++ b/src/scheduler/Scheduler.py @@ -1,4 +1,6 @@ from operator import attrgetter + +from scheduler.templatetags.jdconverter import jdtodate from .UserManager import UserManager from .Interval import * from django.db.models import Q @@ -42,6 +44,7 @@ class Scheduler(IntervalManagement): ''' def copyFromPrevious(self) -> int: if len(Schedule.objects.all()) == 1: + print("only 1 schedule available") self.schedule.plan_night_start = self.schedule.plan_start if DEBUG_FILE: self.log("No schedule found") @@ -97,7 +100,11 @@ class Scheduler(IntervalManagement): self.log("Interval created : " + str(interval.__dict__)) self.removeInvalidSequences() self.determinePriorities() + print("Sequences bef removeNonEligible are:", len(self.sequences)) + # EP le pb est ici !!! + #TODO: bugfix time computation EP a virer (remettre) self.removeNonEligible() + print("Sequences aft removeNonEligible are:", len(self.sequences)) self.sortSequences() self.placeSequences() return 0 @@ -108,6 +115,7 @@ class Scheduler(IntervalManagement): def makeSchedule(self) -> Schedule: print("In makeSchedule()") global SIMULATION + # WHY ??? SIMULATION = False if self.isFirstSchedule(): @@ -117,10 +125,17 @@ class Scheduler(IntervalManagement): #print("It is not the first schedule") self.copyFromPrevious() #TODO trycatch a faire self.schedule.plan_night_start = self.schedule.plan_start + print("night start is", self.schedule.plan_night_start) + + #EP: avirer (add 2 hours) + #self.schedule.plan_night_start += float( (1/24)*2 ) + #self.schedule.plan_start += float( (1/24)*2 ) - # List of sequences (PLANNED, TOBEPLANNED, PENDING) + # Get all sequences which are PLANNED, TOBEPLANNED, or PENDING self.sequences = list(Sequence.objects.filter(Q(status=Sequence.PLANNED) | Q(status=Sequence.TOBEPLANNED) | Q(status=Sequence.PENDING))) + print("**** nb of sequences already available for scheduling", len(self.sequences)) + # List of tuples (sequence, ScheduleHasSequences) for each sequence above and for current schedule self.sequences = [ ( @@ -129,10 +144,11 @@ class Scheduler(IntervalManagement): ) for sequence in self.sequences ] - print("Sequences are:", self.sequences) + print("Sequences BEFORE are:", len(self.sequences)) if DEBUG_FILE: self.log(str(len(self.sequences)) + " sequences found") self.computeSchedule() + print("Sequences AFTER are:", len(self.sequences)) self.saveSchedule() if DEBUG_FILE: self.log("Saving schedule with " + str(len(self.schedule.sequences.all())) + " sequences") @@ -156,6 +172,14 @@ class Scheduler(IntervalManagement): def removeNonEligible(self) -> int: for sequence, shs in list(self.sequences): overlap = Decimal(min(self.schedule.plan_end, sequence.jd2)) - Decimal(max(self.schedule.plan_start, sequence.jd1)) - self.max_overhead + print() + print("- sequence: ", sequence) + print("plan start - plan end:", jdtodate(self.schedule.plan_start), "-", jdtodate(self.schedule.plan_end)) + print("jd1-jd2:", jdtodate(sequence.jd1), "-", jdtodate(sequence.jd2)) + print("overlap < duration ?:", overlap, sequence.duration) + #print("- sequence: ", sequence, "plan start, end, jd1, jd2, overlap", self.schedule.plan_start, self.schedule.plan_end, sequence.jd1, sequence.jd2, overlap) + #print("- sequence: ", sequence, "plan start", jdtodate(self.schedule.plan_start)) + print() if overlap < sequence.duration: if sequence.jd1 < self.schedule.plan_start: sequence.status = Sequence.UNPLANNABLE diff --git a/src/scheduler/tasks.py b/src/scheduler/tasks.py index a0a3b03..6f1466f 100644 --- a/src/scheduler/tasks.py +++ b/src/scheduler/tasks.py @@ -14,8 +14,11 @@ class scheduling(Task): print("In scheduling.run()") task = TaskId.objects.create(task_id=self.request.id, task="scheduling") Log.objects.create(agent='Scheduler', message='Start schedule : ' + str(datetime.datetime.now())) + # This creates a Scheduler (in memory) which creates a Schedule (in DB) self.scheduler = Scheduler() self.scheduler.setNightLimits(secondsToJulianDate(getNightStart()), secondsToJulianDate(getNightEnd())) + print("****sched-task: NEW SCHEDULE", self.scheduler.schedule, "*****") self.scheduler.makeSchedule() + print("****sched-task: NEW SCHEDULE", self.scheduler.schedule, "*****") Log.objects.create(agent='Scheduler', message='Scheduling finished : ' + str(datetime.datetime.now())) task.delete() \ No newline at end of file diff --git a/src/scheduler/templatetags/jdconverter.py b/src/scheduler/templatetags/jdconverter.py index d3ee6f7..c85c844 100644 --- a/src/scheduler/templatetags/jdconverter.py +++ b/src/scheduler/templatetags/jdconverter.py @@ -14,6 +14,10 @@ def jdtodate(jd): hour = str(int(date[3] * 24)) hour = hour if len(hour) == 2 else "0%s" % hour + + # EP avirer + #hour = str(int(hour)+2) + minute = str(int(date[3] * 24 * 60 % 60)) minute = minute if len(minute) == 2 else "0%s" % minute second = str(int(date[3] * 24 * 60 * 60 % 60)) diff --git a/src/scheduler/tests.py b/src/scheduler/tests.py index 7a2f006..e4cee04 100644 --- a/src/scheduler/tests.py +++ b/src/scheduler/tests.py @@ -8,6 +8,7 @@ SIMULATION_FILE = 'file:./scheduler/sequences_cador.html' class SchedulerTest(TestCase): + # (EP) Create a fixture in memory with 1 scheduler, 3 requests belonging to 3 different users def setUp(self): ''' Creates the scheduler @@ -557,16 +558,22 @@ class SchedulerTest(TestCase): def test_4_seq_eligibility(self): ''' - goal: test if inelibigle sequences are programmed + goal: test if ineligible sequences are programmed conditions: only ineligible sequences ''' print("\n===== TEST_4_SEQ_ELIGIBILITY =====\n") + # Check that only 1 EMPTY schedule is available in DB (because of Scheduler() instance created in setup()) + self.assertEqual(len(Schedule.objects.all()) , 1) + sched = Schedule.objects.order_by('-created')[0] + print("schedule is", sched) + self.assertEqual(len(sched.shs.all()), 0) + self.scheduler.schedule.plan_start = 100 self.scheduler.schedule.plan_end = 200 - ''' create the sequences ''' + ''' create 4 sequences (to be planned) with default status TOBEPLANNED ''' seq1 = Sequence.objects.create(request=self.req1, status=Sequence.TOBEPLANNED, name="seq1", jd1=0, jd2=110, priority=1, t_prefered=-1, duration=20) seq2 = Sequence.objects.create(request=self.req2, status=Sequence.TOBEPLANNED, @@ -575,28 +582,38 @@ class SchedulerTest(TestCase): name="seq3", jd1=50, jd2=90, priority=1, t_prefered=-1, duration=20) seq4 = Sequence.objects.create(request=self.req3, status=Sequence.TOBEPLANNED, name="seq4", jd1=300, jd2=400, priority=1, t_prefered=-1, duration=20) + #for s in (seq1,seq2,seq3,seq4): print(s.status) + + # Check that we now have exactly 4 sequences in DB + self.assertEqual(len(Sequence.objects.all()) , 4) ''' compute and print the schedule ''' self.scheduler.makeSchedule() + # Check that still only 1 schedule available in DB, and 0 sequence in it + self.assertEqual(len(Schedule.objects.all()) , 1) + # Get the last (more recent) schedule saved by makeSchedule() sched = Schedule.objects.order_by('-created')[0] + print("updated schedule is", sched, "with night start", sched.plan_night_start) shs_list = sched.shs.all() + # EP added + self.assertEqual(len(shs_list), 0) nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) + self.assertEqual(nbPlanned, 0) + ''' checks sequences status ''' seq1 = Sequence.objects.get(name="seq1") seq2 = Sequence.objects.get(name="seq2") seq3 = Sequence.objects.get(name="seq3") seq4 = Sequence.objects.get(name="seq4") - ''' checks sequences status ''' - - self.assertEqual(nbPlanned, 0) - + for s in (seq1,seq2,seq3,seq4): print(s.status) self.assertEqual(seq1.status, Sequence.UNPLANNABLE) self.assertEqual(seq2.status, Sequence.TOBEPLANNED) self.assertEqual(seq3.status, Sequence.UNPLANNABLE) self.assertEqual(seq4.status, Sequence.TOBEPLANNED) + def test_invalid_sequences(self): ''' goal: test if the scheduler is able to plan invalid sequences (it shouldn't) diff --git a/src/utils/JDManipulator.py b/src/utils/JDManipulator.py index 9ff030b..103c475 100644 --- a/src/utils/JDManipulator.py +++ b/src/utils/JDManipulator.py @@ -17,8 +17,10 @@ def getSimTime(): current_time = current_time.replace(minute=current_time.minute + 1, second=10) else: current_time = current_time.replace(second=(current_time.second + 10)) + return (time.mktime(current_time.timetuple())) + SIM_TIME_START = getSimTime() def JulianSeconds(value): @@ -67,6 +69,12 @@ def getNextDefaultNightEnd(): def getDefaultNightStart(): current_time = datetime.datetime.now() + print("*********************") + print("*********************") + print("current time is", current_time) + print("SIM_TIME_START", SIM_TIME_START) + print("*********************") + print("*********************") if settings.SIMULATOR: if settings.SIMULATOR: return SIM_TIME_START -- libgit2 0.21.2