Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

vigiboard / vigiboard / tests / functional / test_root.py @ 011743be

History | View | Annotate | Download (22.2 KB)

1 57f7cb3f Gabriel DE PERTHUIS
# -*- coding: utf-8 -*-
2 011743be Francois POIROTTE
# Copyright (C) 2006-2020 CS GROUP - France
3 b373a5de Aurelien BOMPARD
# License: GNU GPL v2 <http://www.gnu.org/licenses/gpl-2.0.html>
4
5 57f7cb3f Gabriel DE PERTHUIS
"""
6
Functional test suite for the root controller.
7

8
This is an example of how functional tests can be written for controllers.
9

10
As opposed to a unit-test, which test a small unit of functionality,
11
functional tests exercise the whole application and its WSGI stack.
12

13
Please read http://pythonpaste.org/webtest/ for more information.
14

15
"""
16 2d128717 Vincent QUEMENER
from nose.tools import assert_true, assert_false, assert_equal
17
from datetime import datetime
18 1c5486c7 Francois POIROTTE
from calendar import timegm
19 2d128717 Vincent QUEMENER
import transaction
20
21 e7e3d45e Francois POIROTTE
from vigilo.models.session import DBSession
22 9a05a743 Francois POIROTTE
from vigilo.models.demo import functions
23 8b2edebe Aurelien BOMPARD
from vigilo.models.tables import EventHistory, CorrEvent, User, \
24
                            Permission, Host, UserGroup, DataPermission
25 57f7cb3f Gabriel DE PERTHUIS
from vigiboard.tests import TestController
26 03059edd Francois POIROTTE
from tg import config
27 57f7cb3f Gabriel DE PERTHUIS
28 2d128717 Vincent QUEMENER
def populate_DB():
29
    """ Peuple la base de données. """
30
    # On ajoute un groupe d'hôtes et un groupe de services.
31 9a05a743 Francois POIROTTE
    supitemmanagers = functions.add_supitemgroup(u'managersgroup')
32 24d74687 Francois POIROTTE
33 60d02e7f Francois POIROTTE
    usergroup = UserGroup.by_group_name(u'users_with_access')
34
    DBSession.add(DataPermission(
35
        group=supitemmanagers,
36
        usergroup=usergroup,
37
        access=u'w',
38
    ))
39 2d128717 Vincent QUEMENER
    DBSession.flush()
40
41
    # On crée un 2 hôtes, et on les ajoute au groupe d'hôtes.
42 9a05a743 Francois POIROTTE
    host1 = functions.add_host(u'host1')
43
    host2 = functions.add_host(u'host2')
44 24d74687 Francois POIROTTE
    supitemmanagers.supitems.append(host1)
45
    supitemmanagers.supitems.append(host2)
46 2d128717 Vincent QUEMENER
    DBSession.flush()
47
48
    # On crée 2 services de bas niveau, et on les ajoute au groupe de services.
49 9a05a743 Francois POIROTTE
    service1 = functions.add_lowlevelservice(host1, u'service1')
50
    service2 = functions.add_lowlevelservice(host2, u'service2')
51 24d74687 Francois POIROTTE
    supitemmanagers.supitems.append(service1)
52
    supitemmanagers.supitems.append(service2)
53 2d128717 Vincent QUEMENER
    DBSession.flush()
54 03059edd Francois POIROTTE
55 2d128717 Vincent QUEMENER
    return ([host1, host2], [service1, service2])
56
57 dbbb7938 Francois POIROTTE
def add_correvent_caused_by(supitem, timestamp,
58 8ba2de75 Francois POIROTTE
        correvent_status=CorrEvent.ACK_NONE, event_status=u"WARNING"):
59 2d128717 Vincent QUEMENER
    """
60 03059edd Francois POIROTTE
    Ajoute dans la base de données un évènement corrélé causé
61 2d128717 Vincent QUEMENER
    par un incident survenu sur l'item passé en paramètre.
62
    Génère un historique pour les tests.
63
    """
64
65 9a05a743 Francois POIROTTE
    # Ajout d'un événement brut et d'un événement corrélé.
66
    event = functions.add_event(supitem, event_status, u'foo')
67
    aggregate = functions.add_correvent([event], status=correvent_status)
68 2d128717 Vincent QUEMENER
    return aggregate.idcorrevent
69
70 57f7cb3f Gabriel DE PERTHUIS
71
class TestRootController(TestController):
72 6ab72614 Vincent QUEMENER
    """ Classe de test du root controller """
73 60d02e7f Francois POIROTTE
    def setUp(self):
74
        super(TestRootController, self).setUp()
75
        perm = Permission.by_permission_name(u'vigiboard-access')
76
        perm2 = Permission.by_permission_name(u'vigiboard-update')
77
78
        user = User(
79
            user_name=u'access',
80
            fullname=u'',
81
            email=u'user.has@access',
82
        )
83 03059edd Francois POIROTTE
        usergroup = UserGroup(group_name=u'users_with_access')
84 60d02e7f Francois POIROTTE
        usergroup.permissions.append(perm)
85
        usergroup.permissions.append(perm2)
86
        user.usergroups.append(usergroup)
87
        DBSession.add(user)
88
        DBSession.add(usergroup)
89
        DBSession.flush()
90
91
        user = User(
92
            user_name=u'limited_access',
93
            fullname=u'',
94
            email=u'user.has.no@access',
95
        )
96 03059edd Francois POIROTTE
        usergroup = UserGroup(group_name=u'users_with_limited_access')
97 60d02e7f Francois POIROTTE
        usergroup.permissions.append(perm)
98
        usergroup.permissions.append(perm2)
99
        user.usergroups.append(usergroup)
100
        DBSession.add(user)
101
        DBSession.add(usergroup)
102
        DBSession.flush()
103
104 57f7cb3f Gabriel DE PERTHUIS
    def test_index(self):
105 aa0788a2 Francois POIROTTE
        """Test that access to the root webpage is restricted."""
106
107 f70865a8 Aurelien BOMPARD
        response = self.app.get('/', status=401)
108
        msg = 'Unauthorized'
109 57f7cb3f Gabriel DE PERTHUIS
        assert_true(msg in response)
110 aa0788a2 Francois POIROTTE
111 2d128717 Vincent QUEMENER
    def test_update_host_correvents_status(self):
112
        """Màj du statut d'évènements corrélés causés par des hôtes"""
113
114
        # On peuple la BDD avec 2 hôtes, 2 services de bas niveau,
115
        # et un groupe d'hôtes et de services associés à ces items.
116 8b2edebe Aurelien BOMPARD
        (hosts, _services) = populate_DB()
117 03059edd Francois POIROTTE
118 2d128717 Vincent QUEMENER
        # On ajoute 2 évènements corrélés causés par ces hôtes
119 1c5486c7 Francois POIROTTE
        timestamp = datetime.utcnow()
120 dbbb7938 Francois POIROTTE
        correvent1_id = add_correvent_caused_by(hosts[0], timestamp)
121
        correvent2_id = add_correvent_caused_by(hosts[1], timestamp)
122 2d128717 Vincent QUEMENER
        transaction.commit()
123 03059edd Francois POIROTTE
124 2d128717 Vincent QUEMENER
        ### 1er cas : L'utilisateur n'est pas connecté.
125
        # On vérifie que le plugin retourne bien une erreur 401.
126
        response = self.app.post(
127 dbbb7938 Francois POIROTTE
            '/update', {
128
                "id" : str(correvent1_id) + "," + str(correvent2_id),
129 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
130 dbbb7938 Francois POIROTTE
                "trouble_ticket" : u"foo",
131
                "ack" : u'NoChange',
132
            }, status = 401)
133 03059edd Francois POIROTTE
134 2d128717 Vincent QUEMENER
        ### 2ème cas : L'utilisateur utilisé pour
135 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'limited_access'.
136
        environ = {'REMOTE_USER': 'limited_access'}
137 03059edd Francois POIROTTE
138 2d128717 Vincent QUEMENER
        # On s'attend à ce qu'une erreur 302 soit renvoyée, et à
139
        # ce qu'un message d'erreur précise à l'utilisateur qu'il
140
        # n'a pas la permission de modifier ces évènements.
141
        response = self.app.post(
142 dbbb7938 Francois POIROTTE
            '/update', {
143
                "id" : str(correvent1_id) + "," + str(correvent2_id),
144
                "ack" : u'NoChange',
145
                "trouble_ticket" : u"foo",
146 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
147 dbbb7938 Francois POIROTTE
            }, status = 302, extra_environ = environ)
148 03059edd Francois POIROTTE
149 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
150 2d128717 Vincent QUEMENER
        assert_true(response.lxml.xpath(
151
            '//div[@id="flash"]/div[@class="error"]'))
152
153
        ### 3ème cas : L'utilisateur utilisé pour
154 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'access'.
155
        environ = {'REMOTE_USER': 'access'}
156 03059edd Francois POIROTTE
157 2d128717 Vincent QUEMENER
        # On s'attend à ce que le statut de la requête soit 302,
158
        # et à ce qu'un message informe l'utilisateur que les
159
        # évènements corrélés sélectionnées ont bien été mis à jour.
160
        response = self.app.post(
161 dbbb7938 Francois POIROTTE
            '/update', {
162
                "id" : str(correvent1_id) + "," + str(correvent2_id),
163 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
164 dbbb7938 Francois POIROTTE
                "trouble_ticket" : u"foo",
165
                "ack" : u'NoChange',
166
            }, status = 302, extra_environ = environ)
167 03059edd Francois POIROTTE
168 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
169 2d128717 Vincent QUEMENER
        assert_false(response.lxml.xpath(
170
            '//div[@id="flash"]/div[@class="error"]'))
171
        assert_true(response.lxml.xpath(
172
            '//div[@id="flash"]/div[@class="ok"]'))
173 03059edd Francois POIROTTE
174 2d128717 Vincent QUEMENER
        # On s'assure que le ticket de l'évènement corrélé
175
        # a bien été mis à jour dans la base de données.
176
        correvents = DBSession.query(
177
            CorrEvent.trouble_ticket
178
            ).filter(CorrEvent.idcorrevent.in_([correvent1_id, correvent2_id])
179
            ).all()
180 03059edd Francois POIROTTE
181 2d128717 Vincent QUEMENER
        assert_equal(correvents[0].trouble_ticket, u"foo")
182
        assert_equal(correvents[1].trouble_ticket, u"foo")
183
184
    def test_update_service_correvents_status(self):
185
        """Màj du statut d'évènements corrélés causés par des SBN"""
186
187
        # On peuple la BDD avec 2 hôtes, 2 services de bas niveau,
188
        # et un groupe d'hôtes et de services associés à ces items.
189 8b2edebe Aurelien BOMPARD
        (_hosts, services) = populate_DB()
190 03059edd Francois POIROTTE
191 2d128717 Vincent QUEMENER
        # On ajoute 2 évènements corrélés causés par ces hôtes
192 1c5486c7 Francois POIROTTE
        timestamp = datetime.utcnow()
193 dbbb7938 Francois POIROTTE
        correvent1_id = add_correvent_caused_by(services[0], timestamp)
194
        correvent2_id = add_correvent_caused_by(services[1], timestamp)
195 03059edd Francois POIROTTE
196 2d128717 Vincent QUEMENER
        transaction.commit()
197 03059edd Francois POIROTTE
198 2d128717 Vincent QUEMENER
        ### 1er cas : L'utilisateur n'est pas connecté.
199
        # On vérifie que le plugin retourne bien une erreur 401.
200
        response = self.app.post(
201 dbbb7938 Francois POIROTTE
            '/update', {
202
                "id" : str(correvent1_id) + "," + str(correvent2_id),
203 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
204 dbbb7938 Francois POIROTTE
                "trouble_ticket" : u"foo",
205
                "ack" : u'NoChange',
206
            }, status = 401)
207 03059edd Francois POIROTTE
208 2d128717 Vincent QUEMENER
        ### 2ème cas : L'utilisateur utilisé pour
209 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'limited_access'.
210
        environ = {'REMOTE_USER': 'limited_access'}
211 03059edd Francois POIROTTE
212 2d128717 Vincent QUEMENER
        # On s'attend à ce qu'une erreur 302 soit renvoyée, et à
213
        # ce qu'un message d'erreur précise à l'utilisateur qu'il
214
        # n'a pas la permission de modifier ces évènements.
215
        response = self.app.post(
216 dbbb7938 Francois POIROTTE
            '/update', {
217
                "id" : str(correvent1_id) + "," + str(correvent2_id),
218 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
219 dbbb7938 Francois POIROTTE
                "trouble_ticket" : u"foo",
220
                "ack" : u'NoChange',
221
            }, status = 302, extra_environ = environ)
222 03059edd Francois POIROTTE
223 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
224 2d128717 Vincent QUEMENER
        assert_true(response.lxml.xpath(
225
            '//div[@id="flash"]/div[@class="error"]'))
226
227
        ### 3ème cas : L'utilisateur utilisé pour
228 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'access'.
229
        environ = {'REMOTE_USER': 'access'}
230 03059edd Francois POIROTTE
231 2d128717 Vincent QUEMENER
        # On s'attend à ce que le statut de la requête soit 302,
232
        # et à ce qu'un message informe l'utilisateur que les
233
        # évènements corrélés sélectionnées ont bien été mis à jour.
234
        response = self.app.post(
235 dbbb7938 Francois POIROTTE
            '/update', {
236
                "id" : str(correvent1_id) + "," + str(correvent2_id),
237 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
238 dbbb7938 Francois POIROTTE
                "trouble_ticket" : u"foo",
239
                "ack" : u'NoChange',
240
            }, status = 302, extra_environ = environ)
241 03059edd Francois POIROTTE
242 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
243 2d128717 Vincent QUEMENER
        assert_false(response.lxml.xpath(
244
            '//div[@id="flash"]/div[@class="error"]'))
245
        assert_true(response.lxml.xpath(
246
            '//div[@id="flash"]/div[@class="ok"]'))
247 03059edd Francois POIROTTE
248 2d128717 Vincent QUEMENER
        # On s'assure que le ticket de l'évènement corrélé
249
        # a bien été mis à jour dans la base de données.
250
        correvents = DBSession.query(
251
            CorrEvent.trouble_ticket
252
            ).filter(CorrEvent.idcorrevent.in_([correvent1_id, correvent2_id])
253
            ).all()
254
        assert_equal(correvents[0].trouble_ticket, u"foo")
255
        assert_equal(correvents[1].trouble_ticket, u"foo")
256
257
    def test_update_host_correvents_tickets(self):
258
        """Màj de tickets d'évènements corrélés causés par des hôtes"""
259
260
        # On peuple la BDD avec 2 hôtes, 2 services de bas niveau,
261
        # et un groupe d'hôtes et de services associés à ces items.
262 8b2edebe Aurelien BOMPARD
        (hosts, _services) = populate_DB()
263 03059edd Francois POIROTTE
264 2d128717 Vincent QUEMENER
        # On ajoute 2 évènements corrélés causés par ces hôtes
265 1c5486c7 Francois POIROTTE
        timestamp = datetime.utcnow()
266 dbbb7938 Francois POIROTTE
        correvent1_id = add_correvent_caused_by(hosts[0], timestamp)
267
        correvent2_id = add_correvent_caused_by(hosts[1], timestamp)
268 2d128717 Vincent QUEMENER
        transaction.commit()
269 03059edd Francois POIROTTE
270 2d128717 Vincent QUEMENER
        ### 1er cas : L'utilisateur n'est pas connecté.
271
        # On vérifie que le plugin retourne bien une erreur 401.
272
        response = self.app.post(
273 dbbb7938 Francois POIROTTE
            '/update', {
274
                "id" : str(correvent1_id) + "," + str(correvent2_id),
275 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
276 dbbb7938 Francois POIROTTE
                "trouble_ticket" : "",
277
                "ack" : u'Acknowledged',
278
            }, status = 401)
279 03059edd Francois POIROTTE
280 2d128717 Vincent QUEMENER
        ### 2ème cas : L'utilisateur utilisé pour
281 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'limited_access'.
282
        environ = {'REMOTE_USER': 'limited_access'}
283 03059edd Francois POIROTTE
284 2d128717 Vincent QUEMENER
        # On s'attend à ce qu'une erreur 302 soit renvoyée, et à
285
        # ce qu'un message d'erreur précise à l'utilisateur qu'il
286
        # n'a pas la permission de modifier ces évènements.
287
        response = self.app.post(
288 dbbb7938 Francois POIROTTE
            '/update', {
289
                "id" : str(correvent1_id) + "," + str(correvent2_id),
290 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
291 dbbb7938 Francois POIROTTE
                "trouble_ticket" : "",
292
                "ack" : u'Acknowledged',
293
            }, status = 302, extra_environ = environ)
294 03059edd Francois POIROTTE
295 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
296 2d128717 Vincent QUEMENER
        assert_true(response.lxml.xpath(
297
            '//div[@id="flash"]/div[@class="error"]'))
298
299
        ### 3ème cas : L'utilisateur utilisé pour
300 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'access'.
301
        environ = {'REMOTE_USER': 'access'}
302 03059edd Francois POIROTTE
303 2d128717 Vincent QUEMENER
        # On s'attend à ce que le statut de la requête soit 302,
304
        # et à ce qu'un message informe l'utilisateur que les
305
        # évènements corrélés sélectionnées ont bien été mis à jour.
306
        response = self.app.post(
307 dbbb7938 Francois POIROTTE
            '/update', {
308
                "id" : str(correvent1_id) + "," + str(correvent2_id),
309 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
310 dbbb7938 Francois POIROTTE
                "trouble_ticket" : "",
311
                "ack" : u'Acknowledged',
312
            }, status = 302, extra_environ = environ)
313 03059edd Francois POIROTTE
314 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
315 2d128717 Vincent QUEMENER
        assert_false(response.lxml.xpath(
316
            '//div[@id="flash"]/div[@class="error"]'))
317
        assert_true(response.lxml.xpath(
318
            '//div[@id="flash"]/div[@class="ok"]'))
319 03059edd Francois POIROTTE
320 2d128717 Vincent QUEMENER
        # On s'assure que le statut de l'évènement corrélé
321
        # a bien été mis à jour dans la base de données.
322
        correvents = DBSession.query(
323 8ba2de75 Francois POIROTTE
            CorrEvent.ack
324 2d128717 Vincent QUEMENER
            ).filter(CorrEvent.idcorrevent.in_([correvent1_id, correvent2_id])
325
            ).all()
326 8ba2de75 Francois POIROTTE
        assert_equal(correvents[0].ack, CorrEvent.ACK_KNOWN)
327
        assert_equal(correvents[1].ack, CorrEvent.ACK_KNOWN)
328 2d128717 Vincent QUEMENER
329
330
    def test_update_service_correvents_tickets(self):
331
        """Màj de tickets d'évènements corrélés causés par des SBN"""
332
333
        # On peuple la BDD avec 2 hôtes, 2 services de bas niveau,
334
        # et un groupe d'hôtes et de services associés à ces items.
335 8b2edebe Aurelien BOMPARD
        (_hosts, services) = populate_DB()
336 03059edd Francois POIROTTE
337 2d128717 Vincent QUEMENER
        # On ajoute 2 évènements corrélés causés par ces hôtes
338 1c5486c7 Francois POIROTTE
        timestamp = datetime.utcnow()
339 dbbb7938 Francois POIROTTE
        correvent1_id = add_correvent_caused_by(services[0], timestamp)
340
        correvent2_id = add_correvent_caused_by(services[1], timestamp)
341 03059edd Francois POIROTTE
342 2d128717 Vincent QUEMENER
        transaction.commit()
343 03059edd Francois POIROTTE
344 2d128717 Vincent QUEMENER
        ### 1er cas : L'utilisateur n'est pas connecté.
345
        # On vérifie que le plugin retourne bien une erreur 401.
346
        response = self.app.post(
347 dbbb7938 Francois POIROTTE
            '/update', {
348
                "id" : str(correvent1_id) + "," + str(correvent2_id),
349 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
350 dbbb7938 Francois POIROTTE
                "trouble_ticket" : "",
351
                "ack" : u'Acknowledged',
352
            }, status = 401)
353 03059edd Francois POIROTTE
354 2d128717 Vincent QUEMENER
        ### 2ème cas : L'utilisateur utilisé pour
355 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'limited_access'.
356
        environ = {'REMOTE_USER': 'limited_access'}
357 03059edd Francois POIROTTE
358 2d128717 Vincent QUEMENER
        # On s'attend à ce qu'une erreur 302 soit renvoyée, et à
359
        # ce qu'un message d'erreur précise à l'utilisateur qu'il
360
        # n'a pas la permission de modifier ces évènements.
361
        response = self.app.post(
362 dbbb7938 Francois POIROTTE
            '/update', {
363
                "id" : str(correvent1_id) + "," + str(correvent2_id),
364 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
365 dbbb7938 Francois POIROTTE
                "trouble_ticket" : "",
366
                "ack" : u'Acknowledged',
367
            }, status = 302, extra_environ = environ)
368 03059edd Francois POIROTTE
369 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
370 2d128717 Vincent QUEMENER
        assert_true(response.lxml.xpath(
371
            '//div[@id="flash"]/div[@class="error"]'))
372
373
        ### 3ème cas : L'utilisateur utilisé pour
374 60d02e7f Francois POIROTTE
        # se connecter à Vigiboard est 'access'.
375
        environ = {'REMOTE_USER': 'access'}
376 03059edd Francois POIROTTE
377 2d128717 Vincent QUEMENER
        # On s'attend à ce que le statut de la requête soit 302,
378
        # et à ce qu'un message informe l'utilisateur que les
379
        # évènements corrélés sélectionnées ont bien été mis à jour.
380
        response = self.app.post(
381 dbbb7938 Francois POIROTTE
            '/update', {
382
                "id" : str(correvent1_id) + "," + str(correvent2_id),
383 1c5486c7 Francois POIROTTE
                "last_modification": timegm(timestamp.utctimetuple()),
384 dbbb7938 Francois POIROTTE
                "trouble_ticket" : "",
385
                "ack" : u'Acknowledged',
386
            }, status = 302, extra_environ = environ)
387 03059edd Francois POIROTTE
388 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
389 2d128717 Vincent QUEMENER
        assert_false(response.lxml.xpath(
390
            '//div[@id="flash"]/div[@class="error"]'))
391
        assert_true(response.lxml.xpath(
392
            '//div[@id="flash"]/div[@class="ok"]'))
393 03059edd Francois POIROTTE
394 2d128717 Vincent QUEMENER
        # On s'assure que le statut de l'évènement corrélé
395
        # a bien été mis à jour dans la base de données.
396
        correvents = DBSession.query(
397 8ba2de75 Francois POIROTTE
            CorrEvent.ack
398 2d128717 Vincent QUEMENER
            ).filter(CorrEvent.idcorrevent.in_([correvent1_id, correvent2_id])
399
            ).all()
400 8ba2de75 Francois POIROTTE
        assert_equal(correvents[0].ack, CorrEvent.ACK_KNOWN)
401
        assert_equal(correvents[1].ack, CorrEvent.ACK_KNOWN)
402 2d128717 Vincent QUEMENER
403 3da1d030 Vincent QUEMENER
    def test_update_while_data_have_changed(self):
404 9211ef65 Francois POIROTTE
        """Màj d'un évènement corrélé modifié entre temps."""
405 3da1d030 Vincent QUEMENER
406
        # On peuple la BDD avec 2 hôtes, 2 services de bas niveau,
407
        # et un groupe d'hôtes et de services associés à ces items.
408 8b2edebe Aurelien BOMPARD
        (_hosts, services) = populate_DB()
409 03059edd Francois POIROTTE
410 3da1d030 Vincent QUEMENER
        # On ajoute 2 évènements corrélés causés par ces hôtes
411 1c5486c7 Francois POIROTTE
        timestamp = datetime.utcnow()
412 dbbb7938 Francois POIROTTE
        correvent1_id = add_correvent_caused_by(services[0], timestamp)
413 8b2edebe Aurelien BOMPARD
        add_correvent_caused_by(services[1], timestamp)
414 03059edd Francois POIROTTE
415
        # Date de modification du premier évènement corrélé
416 1c5486c7 Francois POIROTTE
        later_date = datetime.utcnow()
417 3da1d030 Vincent QUEMENER
        # Date du chargement de la page
418 1c5486c7 Francois POIROTTE
        date = timegm(later_date.utctimetuple()) - 42
419 03059edd Francois POIROTTE
420 3da1d030 Vincent QUEMENER
        # On ajoute une entrée dans l'historique de l'évènement brut
421
        # causant le premier évènement corrélé, portant pour timestamp
422
        # une date postérieure à celle du chargement de la page.
423
        correvent1 = DBSession.query(
424
            CorrEvent.idcause
425
            ).filter(CorrEvent.idcorrevent == correvent1_id).one()
426
        DBSession.add(EventHistory(
427
            type_action = u'Nagios update state',
428
            idevent = correvent1.idcause,
429
            timestamp = later_date))
430
        DBSession.flush()
431 03059edd Francois POIROTTE
432 3da1d030 Vincent QUEMENER
        transaction.commit()
433 03059edd Francois POIROTTE
434 60d02e7f Francois POIROTTE
        # L'utilisateur utilisé pour se connecter à Vigiboard est 'access'.
435
        environ = {'REMOTE_USER': 'access'}
436 03059edd Francois POIROTTE
437 3da1d030 Vincent QUEMENER
        # On s'attend à ce que le statut de la requête soit 302, et
438
        # à ce qu'un message d'erreur avise l'utilisateur que des
439
        # changements sont intervenus depuis le chargement de la page.
440
        response = self.app.post(
441 dbbb7938 Francois POIROTTE
            '/update', {
442
                "id" : str(correvent1_id),
443
                "last_modification" : date,
444
                "trouble_ticket" : "",
445
                "ack" : u'Acknowledged',
446
            }, status = 302, extra_environ = environ)
447 03059edd Francois POIROTTE
448 dbbb7938 Francois POIROTTE
        response = response.follow(status=200, extra_environ = environ)
449 3da1d030 Vincent QUEMENER
        assert_true(response.lxml.xpath(
450
            '//div[@id="flash"]/div[@class="warning"]'))
451 03059edd Francois POIROTTE
452 3da1d030 Vincent QUEMENER
        # On s'assure que le statut de l'évènement corrélé
453
        # n'a pas été modifié dans la base de données.
454
        status = DBSession.query(
455 8ba2de75 Francois POIROTTE
            CorrEvent.ack
456 3da1d030 Vincent QUEMENER
            ).filter(CorrEvent.idcorrevent == correvent1_id
457
            ).scalar()
458 8ba2de75 Francois POIROTTE
        assert_equal(status, CorrEvent.ACK_NONE)
459 0bd9c069 Francois POIROTTE
460 03059edd Francois POIROTTE
    def test_close_last_page(self):
461
        """
462
        Suppression de tous les événements de la dernière page.
463

464
        Lorsqu'on supprime tous les événements de la page, on doit
465
        implicitement afficher le contenu de la page d'avant.
466
        """
467
468
        # On crée autant d'événements qu'on peut en afficher par page + 1,
469
        # afin d'avoir 2 pages dans le bac à événements.
470
        items_per_page = int(config['vigiboard_items_per_page'])
471
        for i in xrange(items_per_page + 1):
472
            host = Host(
473 87deba77 Vincent QUEMENER
                name = u'host%d' % (i + 1),
474 03059edd Francois POIROTTE
                snmpcommunity = u'public',
475
                hosttpl = u'/dev/null',
476
                address = u'192.168.1.%d' % i,
477
                snmpport = 42,
478
            )
479
            DBSession.add(host)
480
            DBSession.flush()
481 1c5486c7 Francois POIROTTE
            add_correvent_caused_by(host, datetime.utcnow())
482 87deba77 Vincent QUEMENER
        transaction.commit()
483 03059edd Francois POIROTTE
484
        environ = {'REMOTE_USER': 'manager'}
485
486
        # On vérifie qu'on a 2 pages et que sur la 2ème page,
487
        # il n'y a qu'un seul événement.
488
        response = self.app.get('/?page=2', extra_environ=environ)
489
        current_page = response.lxml.xpath(
490
            '//span[@class="pager_curpage"]/text()')
491
        assert_equal(2, int(current_page[0]))
492 7bde24ad Francois POIROTTE
        assert_equal(len(self.get_rows(response)), 1)
493
        assert_true(len(self.get_cells(response)) > 1)
494 03059edd Francois POIROTTE
495
        # On force l'état de l'événement sur la 2ème page à 'OK'.
496
        # - Tout d'abord, on récupère l'identifiant de l'événement en question.
497 7bde24ad Francois POIROTTE
        idcorrevent = response.lxml.xpath(
498
            'string(//table[contains(concat(" ", @class, " "), " vigitable ")]'
499
            '/tbody/tr/td[@class="plugin_details"]/a/@href)')
500 03059edd Francois POIROTTE
        idcorrevent = int(idcorrevent.lstrip('#'))
501
        # - Puis, on met à jour son état (en le forçant à OK).
502
        # On s'attend à ce que le statut de la requête soit 302,
503
        # et à ce qu'un message informe l'utilisateur que les
504
        # évènements corrélés sélectionnées ont bien été mis à jour.
505
        response = self.app.post(
506
            '/update', {
507
                "id" : str(idcorrevent),
508 1c5486c7 Francois POIROTTE
                "last_modification": timegm(datetime.utcnow().utctimetuple()),
509 03059edd Francois POIROTTE
                "trouble_ticket" : "",
510
                "ack" : u'Forced',
511
            }, status=302, extra_environ=environ)
512
        # - On s'assure que la mise à jour a fonctionné.
513
        response = response.follow(status=200, extra_environ=environ)
514
        assert_false(response.lxml.xpath(
515
            '//div[@id="flash"]/div[@class="error"]'))
516
        assert_true(response.lxml.xpath(
517
            '//div[@id="flash"]/div[@class="ok"]'))
518 87deba77 Vincent QUEMENER
        # - On vérifie qu'on se trouve à présent sur la 1ère page, et que
519
        # l'on y dénombre autant d'évènements qu'on peut en afficher par page
520
        current_page = response.lxml.xpath(
521
            '//span[@class="pager_curpage"]/text()')
522
        assert_equal(1, int(current_page[0]))
523 7bde24ad Francois POIROTTE
        assert_equal(len(self.get_rows(response)), items_per_page)
524
        assert_true(len(self.get_cells(response)) > 1)
525 03059edd Francois POIROTTE
526 87deba77 Vincent QUEMENER
        # Une requête sur la 2ème page doit désormais
527
        # afficher le contenu de la 1ère page.
528 03059edd Francois POIROTTE
        response = self.app.get('/?page=2', extra_environ=environ)
529
        current_page = response.lxml.xpath(
530
            '//span[@class="pager_curpage"]/text()')
531
        assert_equal(1, int(current_page[0]))
532 7bde24ad Francois POIROTTE
        assert_equal(len(self.get_rows(response)), items_per_page)