testAlarm.py 29 KB
Newer Older
Sebastien Robin's avatar
Sebastien Robin committed
1 2
##############################################################################
#
3
# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved.
Sebastien Robin's avatar
Sebastien Robin committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#          Sebastien Robin <seb@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################

29
import unittest
30
import transaction
Sebastien Robin's avatar
Sebastien Robin committed
31 32 33

from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
34
from Products.ERP5Type.tests.utils import DummyMailHost
35 36 37
from AccessControl.SecurityManagement import newSecurityManager, \
        getSecurityManager, setSecurityManager
from AccessControl import Unauthorized
Sebastien Robin's avatar
Sebastien Robin committed
38 39 40 41 42 43 44 45
from DateTime import DateTime
from zLOG import LOG
from Products.ERP5Type.DateUtils import addToDate

class TestAlarm(ERP5TypeTestCase):
  """
  This is the list of test

Aurel's avatar
Aurel committed
46
  test setNextStartDate :
Sebastien Robin's avatar
Sebastien Robin committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
  - every hour
  - at 6, 10, 15, 21 every day
  - every day at 10
  - every 3 days at 14 and 15 and 17
  - every monday and friday, at 6 and 15
  - every 1st and 15th every month, at 12 and 14
  - every 1st day of every 2 month, at 6
  """

  # Different variables used for this test
  run_all_test = 1
  source_company_id = 'Nexedi'
  destination_company_id = 'Coramy'
  component_id = 'brick'
  sales_order_id = '1'
  quantity = 10
  base_price = 0.7832
64
  # year/month/day hour:minute:second
65
  date_format = '%i/%i/%i %i:%i:%d GMT+0100'
Sebastien Robin's avatar
Sebastien Robin committed
66

Sebastien Robin's avatar
Sebastien Robin committed
67 68 69
  def getTitle(self):
    return "Alarm"

Julien Muchembled's avatar
Julien Muchembled committed
70 71 72
  def getBusinessTemplateList(self):
    return ('erp5_base',)

73
  def afterSetUp(self):
74 75 76 77 78
    # add a dummy mailhost to capture alarm notifications
    if 'MailHost' in self.portal.objectIds():
      self.portal.manage_delObjects(['MailHost'])
      self.portal._setObject('MailHost', DummyMailHost('MailHost'))

Sebastien Robin's avatar
Sebastien Robin committed
79 80
    self.login()

81 82 83
  def beforeTearDown(self):
    del self.portal.MailHost._message_list[:]

84
  def newAlarm(self, **kw):
Sebastien Robin's avatar
Sebastien Robin committed
85 86 87 88
    """
    Create an empty alarm
    """
    a_tool = self.getAlarmTool()
89
    return a_tool.newContent(**kw)
Sebastien Robin's avatar
Sebastien Robin committed
90 91 92 93 94 95 96

  def login(self, quiet=0, run=run_all_test):
    uf = self.getPortal().acl_users
    uf._doAddUser('seb', '', ['Manager'], [])
    user = uf.getUserById('seb').__of__(uf)
    newSecurityManager(None, user)

Jérome Perrin's avatar
Jérome Perrin committed
97 98 99 100 101 102 103 104 105 106

  def test_01_HasEverything(self, quiet=0, run=run_all_test):
    # Test if portal_alarms was created
    if not run: return
    if not quiet:
      ZopeTestCase._print('\nTest Has Everything ')
      LOG('Testing... ',0,'testHasEverything')
    self.assertNotEquals(self.portal._getOb('portal_alarms', None), None)
    self.assertNotEquals(self.portal.portal_types.getTypeInfo('Alarm Tool'), None)

Sebastien Robin's avatar
Sebastien Robin committed
107 108 109 110 111 112 113 114 115 116
  def test_02_Initialization(self, quiet=0, run=run_all_test):
    """
    Test some basic things right after the creation
    """
    if not run: return
    if not quiet:
      message = 'Test Initialization'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
    alarm = self.newAlarm()
117
    transaction.commit()
118
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
119 120 121
    now = DateTime()
    date = addToDate(now,day=1)
    alarm.setPeriodicityStartDate(date)
122 123 124
    self.assertEquals(alarm.getAlarmDate(), None)
    alarm.setEnabled(True)
    self.assertEquals(alarm.getAlarmDate(), date)
Sebastien Robin's avatar
Sebastien Robin committed
125 126 127 128 129 130 131 132 133
    alarm.setNextAlarmDate(current_date=now) # This should not do change the alarm date
    self.assertEquals(alarm.getAlarmDate(),date)

  def test_03_EveryHour(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test Every Hour'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
134
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
135
    now = DateTime()
136
    date = addToDate(now, day=2)
Sebastien Robin's avatar
Sebastien Robin committed
137 138
    alarm.setPeriodicityStartDate(date)
    alarm.setPeriodicityHourFrequency(1)
139
    transaction.commit()
140
    self.tic()
Aurel's avatar
Aurel committed
141
    alarm.setNextAlarmDate(current_date=now)
142
    self.assertEquals(alarm.getAlarmDate(), date)
Sebastien Robin's avatar
Sebastien Robin committed
143 144 145
    LOG(message + ' now :',0,now)
    now = addToDate(now,day=2)
    LOG(message + ' now :',0,now)
Aurel's avatar
Aurel committed
146
    alarm.setNextAlarmDate(current_date=now)
Sebastien Robin's avatar
Sebastien Robin committed
147 148 149
    next_date = addToDate(date,hour=1)
    self.assertEquals(alarm.getAlarmDate(),next_date)
    now = addToDate(now,hour=1,minute=5)
Aurel's avatar
Aurel committed
150
    alarm.setNextAlarmDate(current_date=now)
Sebastien Robin's avatar
Sebastien Robin committed
151 152 153 154 155 156 157 158 159
    next_date = addToDate(next_date,hour=1)
    self.assertEquals(alarm.getAlarmDate(),next_date)

  def test_04_Every3Hours(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test Every 3 Hours'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
160
    alarm = self.newAlarm(enabled=True)
161
    now = DateTime().toZone('UTC')
Sebastien Robin's avatar
Sebastien Robin committed
162 163 164 165 166
    hour_to_remove = now.hour() % 3
    now = addToDate(now,hour=-hour_to_remove)
    date = addToDate(now,day=2)
    alarm.setPeriodicityStartDate(date)
    alarm.setPeriodicityHourFrequency(3)
167
    transaction.commit()
168
    self.tic()
Aurel's avatar
Aurel committed
169
    alarm.setNextAlarmDate(current_date=now)
Sebastien Robin's avatar
Sebastien Robin committed
170 171 172 173
    self.assertEquals(alarm.getAlarmDate(),date)
    LOG(message + ' now :',0,now)
    now = addToDate(now,day=2)
    LOG(message + ' now :',0,now)
Aurel's avatar
Aurel committed
174
    alarm.setNextAlarmDate(current_date=now)
Sebastien Robin's avatar
Sebastien Robin committed
175 176 177
    next_date = addToDate(date,hour=3)
    self.assertEquals(alarm.getAlarmDate(),next_date)
    now = addToDate(now,hour=3,minute=7,second=4)
Aurel's avatar
Aurel committed
178
    alarm.setNextAlarmDate(current_date=now)
Sebastien Robin's avatar
Sebastien Robin committed
179 180 181 182 183 184 185 186 187
    next_date = addToDate(next_date,hour=3)
    self.assertEquals(alarm.getAlarmDate(),next_date)

  def test_05_SomeHours(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test Some Hours'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
188 189 190 191 192 193

    right_first_date = DateTime(self.date_format  % (2006,10,6,15,00,00))
    now = DateTime(self.date_format               % (2006,10,6,15,00,00))
    right_second_date = DateTime(self.date_format % (2006,10,6,21,00,00))
    right_third_date = DateTime(self.date_format  % (2006,10,7,06,00,00))
    right_fourth_date = DateTime(self.date_format % (2006,10,7,10,00,00))
194
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
195 196 197
    hour_list = (6,10,15,21)
    alarm.setPeriodicityStartDate(now)
    alarm.setPeriodicityHourList(hour_list)
198
    transaction.commit()
199
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
200
    self.assertEquals(alarm.getAlarmDate(),right_first_date)
Aurel's avatar
Aurel committed
201
    alarm.setNextAlarmDate(current_date=right_first_date)
Sebastien Robin's avatar
Sebastien Robin committed
202
    self.assertEquals(alarm.getAlarmDate(),right_second_date)
Aurel's avatar
Aurel committed
203
    alarm.setNextAlarmDate(current_date=right_second_date)
Sebastien Robin's avatar
Sebastien Robin committed
204
    self.assertEquals(alarm.getAlarmDate(),right_third_date)
Aurel's avatar
Aurel committed
205
    alarm.setNextAlarmDate(current_date=right_third_date)
Sebastien Robin's avatar
Sebastien Robin committed
206 207 208 209 210 211 212 213
    self.assertEquals(alarm.getAlarmDate(),right_fourth_date)

  def test_06_EveryDayOnce(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Every Day Once'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
214 215 216 217 218

    now = DateTime(self.date_format               % (2006,10,6,10,00,00))
    right_first_date = DateTime(self.date_format  % (2006,10,6,10,00,00))
    right_second_date = DateTime(self.date_format % (2006,10,7,10,00,00))
    right_third_date = DateTime(self.date_format  % (2006,10,8,10,00,00))
219
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
220 221 222
    alarm.setPeriodicityStartDate(now)
    alarm.setPeriodicityDayFrequency(1)
    alarm.setPeriodicityHourList((10,))
223
    transaction.commit()
224
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
225
    self.assertEquals(alarm.getAlarmDate(),right_first_date)
Aurel's avatar
Aurel committed
226
    alarm.setNextAlarmDate(current_date=right_first_date)
Sebastien Robin's avatar
Sebastien Robin committed
227
    self.assertEquals(alarm.getAlarmDate(),right_second_date)
Aurel's avatar
Aurel committed
228
    alarm.setNextAlarmDate(current_date=right_second_date)
Sebastien Robin's avatar
Sebastien Robin committed
229 230 231 232 233 234 235 236 237
    self.assertEquals(alarm.getAlarmDate(),right_third_date)

  def test_07_Every3DaysSomeHours(self, quiet=0, run=run_all_test):
    """- every 3 days at 14 and 15 and 17"""
    if not run: return
    if not quiet:
      message = 'Every 3 Days Some Hours'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
238 239 240 241 242

    right_first_date = DateTime(self.date_format % (2006,10,6,14,00,00))
    right_second_date = DateTime(self.date_format  % (2006,10,6,15,00,00))
    right_third_date = DateTime(self.date_format  % (2006,10,6,17,00,00))
    right_fourth_date = DateTime(self.date_format  % (2006,10,9,14,00,00))
243
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
244 245 246
    alarm.setPeriodicityStartDate(right_first_date)
    alarm.setPeriodicityDayFrequency(3)
    alarm.setPeriodicityHourList((14,15,17))
247
    transaction.commit()
248
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
249
    self.assertEquals(alarm.getAlarmDate(),right_first_date)
Aurel's avatar
Aurel committed
250
    alarm.setNextAlarmDate(current_date=right_first_date)
Sebastien Robin's avatar
Sebastien Robin committed
251
    self.assertEquals(alarm.getAlarmDate(),right_second_date)
252 253 254 255 256 257 258 259 260 261 262 263 264
    alarm.setNextAlarmDate(current_date=right_second_date)
    self.assertEquals(alarm.getAlarmDate(),right_third_date)
    alarm.setNextAlarmDate(current_date=right_third_date)
    self.assertEquals(alarm.getAlarmDate(),right_fourth_date)

  def test_07a_Every4DaysSomeHours(self, quiet=0, run=run_all_test):
    """- every 4 days at 14 and 15 and 17"""
    if not run: return
    if not quiet:
      message = 'Every 4 Days Some Hours'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)

265 266 267 268 269
    right_first_date = DateTime(self.date_format % (2006,10,7,13,00,00))
    right_second_date = DateTime(self.date_format  % (2006,10,8,14,00,00))
    right_third_date = DateTime(self.date_format  % (2006,10,8,15,00,00))
    right_fourth_date = DateTime(self.date_format  % (2006,10,8,17,00,00))
    right_fifth_date = DateTime(self.date_format  % (2006,10,12,14,00,00))
270
    alarm = self.newAlarm(enabled=True)
271 272 273
    alarm.setPeriodicityStartDate(right_first_date)
    alarm.setPeriodicityDayFrequency(4)
    alarm.setPeriodicityHourList((14,15,17))
274
    transaction.commit()
275 276 277 278
    self.tic()
    self.assertEquals(alarm.getAlarmDate(),right_first_date)
    alarm.setNextAlarmDate(current_date=right_first_date)
    self.assertEquals(alarm.getAlarmDate(),right_second_date)
Aurel's avatar
Aurel committed
279
    alarm.setNextAlarmDate(current_date=right_second_date)
Sebastien Robin's avatar
Sebastien Robin committed
280
    self.assertEquals(alarm.getAlarmDate(),right_third_date)
Aurel's avatar
Aurel committed
281
    alarm.setNextAlarmDate(current_date=right_third_date)
Sebastien Robin's avatar
Sebastien Robin committed
282
    self.assertEquals(alarm.getAlarmDate(),right_fourth_date)
283 284
    alarm.setNextAlarmDate(current_date=right_fourth_date)
    self.assertEquals(alarm.getAlarmDate(),right_fifth_date)
Sebastien Robin's avatar
Sebastien Robin committed
285 286 287 288 289 290 291 292

  def test_08_SomeWeekDaysSomeHours(self, quiet=0, run=run_all_test):
    """- every monday and friday, at 6 and 15"""
    if not run: return
    if not quiet:
      message = 'Some Week Days Some Hours'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
293 294

    right_first_date = DateTime(self.date_format  % (2006,9,27,6,00,00))
295 296 297 298
    right_second_date = DateTime(self.date_format  % (2006,9,29,6,00,00))
    right_third_date = DateTime(self.date_format  % (2006,9,29,15,00,00))
    right_fourth_date = DateTime(self.date_format  % (2006,10,2,6,00,00))
    right_fifth_date = DateTime(self.date_format  % (2006,10,2,15,00,00))
299
    alarm = self.newAlarm(enabled=True)
300
    transaction.commit()
301
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
302 303 304 305 306 307 308 309 310 311 312 313
    alarm.setPeriodicityStartDate(right_first_date)
    alarm.setPeriodicityWeekDayList(('Monday','Friday'))
    alarm.setPeriodicityHourList((6,15))
    self.checkDate(alarm, right_first_date, right_second_date, right_third_date, right_fourth_date)

  def checkDate(self,alarm,*args):
    """
    the basic test
    """
    for date in args[:-1]:
      LOG('checkDate, checking date...:',0,date)
      self.assertEquals(alarm.getAlarmDate(),date)
Aurel's avatar
Aurel committed
314
      alarm.setNextAlarmDate(current_date=date)
Sebastien Robin's avatar
Sebastien Robin committed
315 316 317 318 319 320 321 322 323
    self.assertEquals(alarm.getAlarmDate(),args[-1])

  def test_09_SomeMonthDaysSomeHours(self, quiet=0, run=run_all_test):
    """- every 1st and 15th every month, at 12 and 14"""
    if not run: return
    if not quiet:
      message = 'Some Month Days Some Hours'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
324 325 326 327 328

    right_first_date = DateTime(self.date_format  % (2006,10,01,12,00,00))
    right_second_date = DateTime(self.date_format  % (2006,10,01,14,00,00))
    right_third_date = DateTime(self.date_format  % (2006,10,15,12,00,00))
    right_fourth_date = DateTime(self.date_format  % (2006,10,15,14,00,00))
329
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
330 331 332
    alarm.setPeriodicityStartDate(right_first_date)
    alarm.setPeriodicityMonthDayList((1,15))
    alarm.setPeriodicityHourList((12,14))
333
    transaction.commit()
334
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
335 336 337 338 339 340 341 342 343
    self.checkDate(alarm, right_first_date, right_second_date, right_third_date, right_fourth_date)

  def test_10_OnceEvery2Month(self, quiet=0, run=run_all_test):
    """- every 1st day of every 2 month, at 6"""
    if not run: return
    if not quiet:
      message = 'Once Every 2 Month'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
344 345 346 347

    right_first_date = DateTime(self.date_format  % (2006,10,01,6,00,00))
    right_second_date = DateTime(self.date_format  % (2006,12,01,6,00,00))
    right_third_date = DateTime(self.date_format  % (2007,2,01,6,00,00))
348
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
349 350 351 352
    alarm.setPeriodicityStartDate(right_first_date)
    alarm.setPeriodicityMonthDayList((1,))
    alarm.setPeriodicityMonthFrequency(2)
    alarm.setPeriodicityHourList((6,))
353
    transaction.commit()
354
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
355 356 357 358 359 360 361 362
    self.checkDate(alarm, right_first_date, right_second_date, right_third_date)

  def test_11_EveryDayOnceWeek41And42(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Every Day Once Week 41 And 43'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
363 364 365 366 367

    right_first_date = DateTime(self.date_format  % (2006,10,1,6,00,00))
    right_second_date = DateTime(self.date_format  % (2006,10,9,6,00,00))
    right_third_date = DateTime(self.date_format  % (2006,10,10,6,00,00))
    right_fourth_date = DateTime(self.date_format  % (2006,10,11,6,00,00))
368
    alarm = self.newAlarm(enabled=True)
Sebastien Robin's avatar
Sebastien Robin committed
369 370 371
    alarm.setPeriodicityStartDate(right_first_date)
    alarm.setPeriodicityHourList((6,))
    alarm.setPeriodicityWeekList((41,43))
372
    transaction.commit()
373
    self.tic()
Sebastien Robin's avatar
Sebastien Robin committed
374 375
    self.checkDate(alarm, right_first_date, right_second_date, right_third_date,right_fourth_date)

Aurel's avatar
Aurel committed
376 377 378 379 380 381
  def test_12_Every5Minutes(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test Every 5 Minutes'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
382
    alarm = self.newAlarm(enabled=True)
Aurel's avatar
Aurel committed
383 384 385 386 387 388
    now = DateTime()
    minute_to_remove = now.minute() % 5
    now = addToDate(now,minute=-minute_to_remove)
    date = addToDate(now,day=2)
    alarm.setPeriodicityStartDate(date)
    alarm.setPeriodicityMinuteFrequency(5)
389
    transaction.commit()
390
    self.tic()
Aurel's avatar
Aurel committed
391 392 393 394 395 396 397 398 399 400 401 402
    alarm.setNextAlarmDate(current_date=now)
    self.assertEquals(alarm.getAlarmDate(),date)
    LOG(message + ' now :',0,now)
    now = addToDate(now,day=2)
    LOG(message + ' now :',0,now)
    alarm.setNextAlarmDate(current_date=now)
    next_date = addToDate(date,minute=5)
    self.assertEquals(alarm.getAlarmDate(),next_date)
    now = addToDate(now,minute=5,second=14)
    alarm.setNextAlarmDate(current_date=now)
    next_date = addToDate(next_date,minute=5)
    self.assertEquals(alarm.getAlarmDate(),next_date)
Sebastien Robin's avatar
Sebastien Robin committed
403

404 405 406 407 408 409
  def test_13_EveryMinute(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test Every Minute'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
410
    alarm = self.newAlarm(enabled=True)
411 412 413 414
    now = DateTime()
    date = addToDate(now,hour=2)
    alarm.setPeriodicityStartDate(now)
    alarm.setPeriodicityMinuteFrequency(1)
415
    transaction.commit()
416 417 418 419
    self.tic()
    alarm.setNextAlarmDate(current_date=date)
    self.assertEquals(alarm.getAlarmDate(),date)

420 421 422 423 424 425
  def test_14_NewActiveProcess(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test New Active Process'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
426
    alarm = self.newAlarm(enabled=True)
427 428 429
    active_process = alarm.newActiveProcess()
    self.assertEquals('Active Process', active_process.getPortalType())
    self.assertEquals(alarm, active_process.getCausalityValue())
430
    transaction.commit()
431 432
    self.tic()
    self.assertEquals(active_process, alarm.getLastActiveProcess())
433 434 435 436 437 438 439

  def test_15_FailedAlarmsDoNotBlockFutureAlarms(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      message = 'Test Failed Alarms Do Not Block Future Alarms'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
440
    try:
441 442 443 444 445 446 447
      sense_method_id = 'Alarm_testSenseMethod'
      skin_folder_id = 'custom'
      skin_folder = self.getPortal().portal_skins[skin_folder_id]
      skin_folder.manage_addProduct['PythonScripts'].manage_addPythonScript(id=sense_method_id)
      # Make the sense method fail
      skin_folder[sense_method_id].ZPythonScript_edit('*args,**kw', 'raise Exception')
      del skin_folder
448
      alarm = self.newAlarm(enabled=True)
449
      transaction.commit()
450
      self.tic()
451 452 453 454
      now = DateTime()
      alarm.setActiveSenseMethodId(sense_method_id)
      self.assertEquals(alarm.isActive(), 0)
      alarm.activeSense()
455
      transaction.commit()
456 457 458 459 460 461 462 463 464 465 466 467 468
      try:
        self.tic()
      except RuntimeError:
        pass
      else:
        raise Exception, 'Tic did not raise though activity was supposed to fail'
      # Check that the alarm is not considered active, although there is a remaining activity.
      self.assertEquals(alarm.hasActivity(), 1)
      self.assertEquals(alarm.isActive(), 0)
      self.assertEquals(alarm.getLastActiveProcess(), None)
      # Make the sense method succeed and leave a trace
      self.getPortal().portal_skins[skin_folder_id][sense_method_id].ZPythonScript_edit('*args,**kw', 'context.newActiveProcess()')
      alarm.activeSense()
469
      transaction.commit()
470 471 472 473 474 475 476 477 478 479 480 481 482
      # Note: this call to tic will fail, because the previous message is still there
      # This behaviour is logical if we consider that we want to keep errors
      # in order to know that an error occured.
      try:
        self.tic()
      except RuntimeError:
        pass
      else:
        raise Exception, 'Tic did not raise though activity was supposed to fail'
      # Chen that the second alarm execution did happen
      self.assertNotEquals(alarm.getLastActiveProcess(), None)
    finally:
      self.portal.portal_activities.manageClearActivities(keep=0)
483

484 485
  def test_16_uncatalog(self, quiet=0, run=run_all_test):
    """
486
    Check that deleting an alarm uncatalogs it.
487 488 489 490 491 492
    """
    if not run: return
    if not quiet:
      message = 'Test Uncatalog'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ', 0, message)
493
    alarm = self.newAlarm(enabled=True)
494
    transaction.commit()
495 496 497 498 499
    self.tic()

    now = DateTime()
    date = addToDate(now, day=1)
    alarm.setPeriodicityStartDate(date)
500
    transaction.commit()
501 502 503 504 505
    self.tic()
    self.assertEquals(alarm.getAlarmDate(), date)

    # This should not do change the alarm date
    alarm.setNextAlarmDate(current_date=now)
506
    transaction.commit()
507 508 509 510 511 512 513
    self.tic()
    self.assertEquals(alarm.getAlarmDate(), date)

    # Delete the alarm
    a_tool = self.getAlarmTool()
    alarm_uid = alarm.getUid()
    a_tool.manage_delObjects(uids=[alarm_uid])
514
    transaction.commit()
515 516 517 518 519 520
    self.tic()
    # Check that related entry was removed
    sql_connection = self.getSQLConnection()
    sql = 'select * from alarm where uid=%s' % alarm_uid
    result = sql_connection.manage_test(sql)
    self.assertEquals(0, len(result))
521

522 523 524 525 526 527 528 529 530 531 532
  def test_17_tic(self, quiet=0, run=run_all_test):
    """
    Make sure that the tic method on alarm is working
    """
    if not run: return
    if not quiet:
      message = 'Test AlarmTool Tic'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ', 0, message)
    alarm = self.newAlarm()
    alarm.setEnabled(True)
533
    transaction.commit()
534 535 536 537 538 539 540 541 542 543 544 545
    self.tic()

    sense_method_id = 'Alarm_testSenseMethodForTic'
    skin_folder_id = 'custom'
    skin_folder = self.getPortal().portal_skins[skin_folder_id]
    skin_folder.manage_addProduct['PythonScripts']\
        .manage_addPythonScript(id=sense_method_id)
    # Make the sense method fail
    skin_folder[sense_method_id].ZPythonScript_edit('*args,**kw', 
          'context.setDescription("a")')
    del skin_folder
    alarm.setActiveSenseMethodId(sense_method_id)
546
    transaction.commit()
547 548 549 550
    self.tic()
    alarm_tool = self.getPortal().portal_alarms
    # Nothing should happens yet
    alarm_tool.tic()
551 552
    transaction.commit()
    self.tic()
553 554
    self.assertTrue(alarm.getDescription() in (None, ''))
    now = DateTime()
555
    date = addToDate(now, day=-1)
556 557
    alarm.setPeriodicityStartDate(date)
    alarm.setPeriodicityMinuteFrequency(1)
558
    transaction.commit()
559 560
    self.tic()
    alarm_tool.tic()
561 562
    transaction.commit()
    self.tic()
563 564
    self.assertEquals(alarm.getDescription(), 'a')

565 566
  def test_18_alarm_activities_execution_order(self, quiet=0, run=run_all_test):
    """
567
    Make sure active process created by an alarm get the right tag
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
    """
    if not run: return
    if not quiet:
      message = 'Test Activities execution order'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ', 0, message)

    alarm = self.newAlarm()
    # Create script that generate active process
    sense_method_id = 'Alarm_createActiveProcessSenseMethod'
    skin_folder_id = 'custom'
    skin_folder = self.getPortal().portal_skins[skin_folder_id]
    skin_folder.manage_addProduct['PythonScripts']\
        .manage_addPythonScript(id=sense_method_id)
    skin_folder[sense_method_id].ZPythonScript_edit('*args,**kw', 
          'context.newActiveProcess()')
    # update alarm properties
    alarm.edit(alarm_notification_mode="always",
               active_sense_method_id=sense_method_id,
               enabled=True)
588
    transaction.commit()
589 590
    self.tic()
    alarm.activeSense()
591
    transaction.commit()
592 593
    messages_list = self.getActivityTool().getMessageList()
    self.assertEquals(2, len(messages_list))
594
    expected_tag = alarm.getRelativeUrl() + '_0'
595 596 597
    # check tags after activeSense
    for m in messages_list:
      if m.method_id == 'notify':
598
        self.assertEqual(expected_tag, m.activity_kw.get('after_tag'))
599
      elif m.method_id == sense_method_id:
600
        self.assertEqual(expected_tag, m.activity_kw.get('tag'))
601
      else:
Julien Muchembled's avatar
Julien Muchembled committed
602
        self.fail(m.method_id)
603 604
    # execute alarm sense script and check tags
    self.getActivityTool().manageInvoke(alarm.getPhysicalPath(),sense_method_id)
605
    transaction.commit()
606 607 608
    messages_list = self.getActivityTool().getMessageList()
    for m in messages_list:
      if m.method_id == 'notify':
609
        self.assertEqual(expected_tag, m.activity_kw.get('after_tag'))
610
      elif m.method_id == 'immediateReindexObject':
611
        self.assertEqual(expected_tag, m.activity_kw.get('tag'))
612
      else:
Julien Muchembled's avatar
Julien Muchembled committed
613 614
        self.fail(m.method_id)
    self.tic()
615

616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
  def test_19_ManualInvocation(self, quiet=0, run=run_all_test):
    """
    test if an alarm can be invoked directly by the user securely,
    and if the results are identical when allowed.
    """
    if not run: return
    if not quiet:
      message = 'Test manual invocation'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ', 0, message)

    alarm = self.newAlarm()
    # Create script that generate active process
    sense_method_id = 'Alarm_setBogusLocalProperty'
    skin_folder_id = 'custom'
631
    skin_folder = self.portal.portal_skins[skin_folder_id]
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
    skin_folder.manage_addProduct['PythonScripts']\
        .manage_addPythonScript(id=sense_method_id)
    skin_folder[sense_method_id].ZPythonScript_edit('*args,**kw', 
          'context.setProperty("bogus", str(context.showPermissions()))')

    # update alarm properties
    alarm.edit(active_sense_method_id=sense_method_id,
               enabled=False)
    transaction.commit()
    self.tic()

    # Make a normal user.
    uf = self.getPortal().acl_users
    uf._doAddUser('normal', '', ['Member', 'Auditor'], [])
    user = uf.getUserById('normal').__of__(uf)
647
    
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
    # Check the pre-conditions.
    self.assertEquals(alarm.getProperty('bogus', None), None)
    self.assertEquals(alarm.getEnabled(), False)
    sm = getSecurityManager()
    newSecurityManager(None, user)

    # Non-managers must not be able to invoke a disabled alarm.
    self.assertRaises(Unauthorized, alarm.activeSense)
    self.assertRaises(Unauthorized, alarm.activeSense, fixit=1)

    # Non-managers must not be able to invoke the automatic fixation.
    setSecurityManager(sm)
    alarm.setEnabled(True)
    self.assertEquals(alarm.getEnabled(), True)
    newSecurityManager(None, user)
    self.assertRaises(Unauthorized, alarm.activeSense, fixit=1)

    # Now, check that everybody can invoke an enabled alarm manually.
    setSecurityManager(sm)
    correct_answer = str(alarm.showPermissions())
    self.assertNotEquals(correct_answer, None)

    alarm.activeSense()
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getProperty('bogus', None), correct_answer)
    alarm.setProperty('bogus', None)
    self.assertEquals(alarm.getProperty('bogus', None), None)

    newSecurityManager(None, user)
    alarm.activeSense()
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getProperty('bogus', None), correct_answer)
    setSecurityManager(sm)
    alarm.setProperty('bogus', None)

    # Check that Manager can invoke an alarm freely.
    alarm.activeSense(fixit=1)
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getProperty('bogus', None), correct_answer)
    alarm.setProperty('bogus', None)
    self.assertEquals(alarm.getProperty('bogus', None), None)

    alarm.setEnabled(False)
    self.assertEquals(alarm.getEnabled(), False)

    alarm.activeSense()
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getProperty('bogus', None), correct_answer)
    alarm.setProperty('bogus', None)
    self.assertEquals(alarm.getProperty('bogus', None), None)

    alarm.activeSense(fixit=1)
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getProperty('bogus', None), correct_answer)
    alarm.setProperty('bogus', None)
    self.assertEquals(alarm.getProperty('bogus', None), None)

710 711 712 713 714 715 716 717 718
  def test_20_UndefinedPeriodicityStartDate(self, quiet=0, run=run_all_test):
    """
    Test that getAlarmDate does not crash when PeriodicityStartDate is not set.
    """
    if not run: return
    if not quiet:
      message = 'Test undefined PeriodicityStartDate'
      ZopeTestCase._print('\n%s ' % message)
      LOG('Testing... ',0,message)
719
    alarm = self.newAlarm(enabled=True)
720 721 722 723
    # Test sanity check.
    self.assertEqual(alarm.getPeriodicityStartDate(), None)
    # Actual test.
    self.assertEquals(alarm.getAlarmDate(), None)
724

725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
  def test_21_AlarmCatalogPresence(self):
    """Check that alarm date is properly stored in catalog upon first reindexation"""
    date = DateTime().earliestTime()
    alarm = self.newAlarm(enabled=True, periodicity_start_date=date)
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getAlarmDate(), date)
    alarm_list = alarm.Alarm_zGetAlarmDate(uid=alarm.getUid())
    self.assertEqual(1, len(alarm_list))
    catalog_alarm_date = alarm_list[0].alarm_date
    self.assertEqual(date.toZone('UTC'), catalog_alarm_date)

  def test_21a_AlarmCatalogPresenceDoubleReindex(self):
    """Check that alarm date is properly stored in catalog"""
    date = DateTime().earliestTime()
    alarm = self.newAlarm(enabled=True, periodicity_start_date=date)
    transaction.commit()
    self.tic()
    alarm.recursiveReindexObject()
    transaction.commit()
    self.tic()
    self.assertEquals(alarm.getAlarmDate(), date)
    alarm_list = alarm.Alarm_zGetAlarmDate(uid=alarm.getUid())
    self.assertEqual(1, len(alarm_list))
    catalog_alarm_date = alarm_list[0].alarm_date
    self.assertEqual(date.toZone('UTC'), catalog_alarm_date)

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
  def test_21b_AlarmCatalogPresenceWithInitialEmptyStartDate(self):
    """Check that alarm date is properly stored in catalog if
       initially the periodicity start date was not there and
       then set later"""
    date = DateTime().earliestTime()
    alarm = self.newAlarm(enabled=True, periodicity_start_date=None)
    transaction.commit()
    self.tic()
    alarm_list = alarm.Alarm_zGetAlarmDate(uid=alarm.getUid())
    self.assertEqual(None, alarm_list[0].alarm_date)
    alarm.edit(periodicity_start_date=date)
    transaction.commit()
    self.tic()
    alarm_list = alarm.Alarm_zGetAlarmDate(uid=alarm.getUid())
    self.assertEqual(date.toZone('UTC'), alarm_list[0].alarm_date)

768 769 770 771
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestAlarm))
  return suite
Sebastien Robin's avatar
Sebastien Robin committed
772