test.py 12.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# -*- coding: utf-8 -*-
# Copyright (C) Brian Moe, Branson Stephens (2015)
#
# This file is part of gracedb
#
# gracedb 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 3 of the License, or
# (at your option) any later version.
#
# It 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 gracedb.  If not, see <http://www.gnu.org/licenses/>.
18 19 20 21

import unittest
import random
import os
22 23
from datetime import datetime
import time
24

25
from ligo.gracedb.rest import GraceDb, GraceDbBasic
26

27 28 29 30 31 32 33 34 35
# Test the GraceDb REST API class.
#
#  To run:
#
#     python $PATH_TO_GRACEDB_LIB/test/test.py
# 
#  Environment Variables:
#
#     TEST_SERVICE
36
#       defaults to https://moe.phys.uwm.edu/branson/api/
37 38 39 40 41 42 43 44 45 46 47 48 49
#       live site would be https://gracedb.ligo.org/api/
#
#     TEST_DATA_DIR
#       defaults to $PATH_TO_GRACEDB_LIB/test/data/
#
#       Files expected:
#
#          burst-cwb.txt
#          cbc-lm2.xml
#          cbc-lm.xml
#          cbc-mbta.gwf
#          upload2.data
#          upload.data
50
#          upload.data.gz
51 52 53 54 55 56 57
#
#     X509_USER_PROXY
#
#     X509_USER_CERT
#     X509_USER_KEY


58 59 60
TEST_SERVICE = "https://gracedb-test.ligo.org/apiweb/"
TEST_SP_SESSION_ENDPOINT = "https://gracedb-test.ligo.org/Shibboleth.sso/Session"
SLEEP_TIME = 1
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91

class TestGracedb(unittest.TestCase):
    """
        This is as much a test of the REST API on the server
        as it is of the REST client.

        Requires a valid x509 cert in a place that the GraceDb
        class can find it and that the cert DN is accepted by
        the test service.

        This is not a complete set of unit tests,
        but it is a decent start.
    """

    def test_root(self):
        """Did root resource retrieval succeed?"""
        self.assertTrue("CBC" in gracedb.groups)
        pass

    def test_get_events(self):
        """Get the events resource.  Make sure first event looks like an event."""
        events = gracedb.events()
        for event in events:
            self.assertTrue('graceid' in event)
            break

    def test_create_log(self):
        """Create an event log message"""
        message = "Message is {0}".format(random.random())
        resp = gracedb.writeLog(eventId, message)
        self.assertEqual(resp.status, 201)
92
        new_log_uri = resp.info().getheader('Location')
93 94 95 96 97 98 99 100 101 102 103
        new_log = resp.json()
        self.assertEqual(new_log_uri, new_log['self'])
        check_new_log = gracedb.get(new_log_uri).json()
        self.assertEqual(check_new_log['comment'], message)

    def test_get_log(self):
        """Retrieve event log"""
        logs = gracedb.logs(eventId).json()
        self.assertTrue('numRows' in logs)
        pass

104 105
    def test_create_emobservation(self):
        """Create an EM observation entry."""
106
        comment = "Message is {0}".format(random.random())
107 108 109 110 111 112 113 114 115 116 117
        # Let's put in some made-up values
        raList = [1.0,1.0,1.0]
        raWidthList = 1.0
        decList = [1.0,1.0,1.0]
        decWidthList = 1.0
        dt = datetime(1900,1,1,1,1,1)
        startTimeList = [dt.isoformat() for i in range(3)]
        durationList = 1.0
        resp = gracedb.writeEMObservation(eventId, 'Test',
            raList, raWidthList, decList, decWidthList,
            startTimeList, durationList, comment)
118
        self.assertEqual(resp.status, 201)
119 120 121 122 123
        new_emobservation_uri = resp.info().getheader('Location')
        new_emobservation = resp.json()
        self.assertEqual(new_emobservation_uri, new_emobservation['self'])
        check_new_emobservation = gracedb.get(new_emobservation_uri).json()
        self.assertEqual(check_new_emobservation['comment'], comment)
124

125 126 127 128
    def test_get_emobservations(self):
        """Retrieve EM Observation List"""
        emos = gracedb.emobservations(eventId).json()
        self.assertTrue('numRows' in emos)
129

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    def test_upload_large_file(self):
        """Upload a large file.  Issue https://bugs.ligo.org/redmine/issues/951"""

        uploadFile = os.path.join(testdatadir, "big.data")
        r = gracedb.writeFile(eventId, uploadFile)
        self.assertEqual(r.status, 201) # CREATED
        r_content = r.json()
        link = r_content['permalink']
        self.assertEqual(
                open(uploadFile, 'r').read(),
                gracedb.get(gracedb.files(eventId).json()['big.data']).read()
                )
        self.assertEqual(
                open(uploadFile, 'r').read(),
                gracedb.get(link).read()
                )

147 148 149 150
    def test_upload_file(self):
        """Upload and re-upload a file"""

        uploadFile = os.path.join(testdatadir, "upload.data")
151
        r = gracedb.writeFile(eventId, uploadFile)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
        self.assertEqual(r.status, 201) # CREATED
        r_content = r.json()
        link = r_content['permalink']

        self.assertEqual(
                open(uploadFile, 'r').read(),
                gracedb.get(gracedb.files(eventId).json()['upload.data']).read()
                )

        self.assertEqual(
                open(uploadFile, 'r').read(),
                gracedb.get(link).read()
                )

        # Re-upload slightly different file.
        uploadFile2 = os.path.join(testdatadir, "upload2.data")
        r = gracedb.writeFile(
                eventId,
                filename="upload.data",
                filecontents=open(uploadFile2, 'r'))
        self.assertEqual(r.status, 201) # CREATED
        r_content = r.json()
        link2 = r_content['permalink']

        self.assertEqual(
                open(uploadFile2, 'r').read(),
                gracedb.get(gracedb.files(eventId).json()['upload.data']).read()
                )

        self.assertEqual(
                open(uploadFile2, 'r').read(),
                gracedb.get(link2).read()
                )

        self.assertNotEqual(link, link2)


    def test_files(self):
        """Get file info"""
        r = gracedb.files(eventId)
        event = r.json()
        self.assertEqual(r.status, 200)
        self.assertTrue(isinstance(event, dict))

    def test_label_event(self):
        """Label an event"""
        r = gracedb.writeLabel(eventId, "DQV")
        self.assertEqual(r.status, 201) # CREATED
        r = gracedb.labels(eventId, "DQV")
        self.assertEqual(r.status, 200)
        label = r.json()
        self.assertEqual("DQV", label['name'])

    def test_create_cwb(self):
        """Create a CWB event"""
        """burst-cwb.txt"""
208
        time.sleep(SLEEP_TIME)
209 210 211 212 213
        eventFile = os.path.join(testdatadir, "burst-cwb.txt")
        r = gracedb.createEvent("Test", "CWB", eventFile)
        self.assertEqual(r.status, 201) # CREATED
        cwb_event = r.json()
        self.assertEqual(cwb_event['group'], "Test")
214
        self.assertEqual(cwb_event['pipeline'], "CWB")
215
        self.assertEqual(float(cwb_event['gpstime']), 1042312876.5090)
216 217 218 219 220 221 222 223 224

    def test_create_lowmass(self):
        """Create a Low Mass event"""
        """cbc-lm.xml"""
        # This is done with the initially created event.
        pass

    def test_create_mbta(self):
        """Create an MBTA event"""
225
        """cbc-mbta.xml"""
226
        time.sleep(SLEEP_TIME)
227
        eventFile = os.path.join(testdatadir, "cbc-mbta.xml")
228
        mbta_event = gracedb.createEvent(
229
                "Test", "MBTAOnline", eventFile).json()
230
        self.assertEqual(mbta_event['group'], "Test")
231
        self.assertEqual(mbta_event['pipeline'], "MBTAOnline")
232
        self.assertEqual(float(mbta_event['gpstime']), 1078903329.421037)
233
        self.assertEqual(mbta_event['far'], 4.006953918826065e-7)
234

235 236 237 238 239 240 241 242 243 244 245 246 247
    def test_create_hardwareinjection(self):
        """Create a HardwareInjection event"""
        """sim-inj.xml"""
        time.sleep(SLEEP_TIME)
        eventFile = os.path.join(testdatadir, "sim-inj.xml")
        hardwareinjection_event = gracedb.createEvent(
                "Test", "HardwareInjection", eventFile,
                instrument="H1", source_channel="",
                destination_channel="").json()
        self.assertEqual(hardwareinjection_event['group'], "Test")
        self.assertEqual(hardwareinjection_event['pipeline'], "HardwareInjection")
        self.assertEqual(hardwareinjection_event['instruments'], "H1")

248
    def test_replace_event(self):
249
        time.sleep(SLEEP_TIME)
250 251 252 253
        graceid = eventId

        old_event = gracedb.event(graceid).json()
        self.assertEqual(old_event['group'], "Test")
254
        self.assertEqual(old_event['search'], "LowMass")
255
        self.assertEqual(float(old_event['gpstime']), 971609248.151741)
256 257 258 259 260 261 262 263

        replacementFile = os.path.join(testdatadir, "cbc-lm2.xml")

        response = gracedb.replaceEvent(graceid, replacementFile)
        self.assertEqual(response.status, 202)

        new_event = gracedb.event(graceid).json()
        self.assertEqual(new_event['group'], "Test")
264
        self.assertEqual(new_event['search'], "LowMass")
265
        self.assertEqual(float(new_event['gpstime']), 971609249.151741)
266

267 268 269 270 271 272 273 274 275 276
    def test_upload_binary(self):
        """
        Test workaround for Python bug
        http://bugs.python.org/issue11898
        Raises exception if workaround fails.
        """
        uploadFile = os.path.join(testdatadir, "upload.data.gz")
        r = gracedb.writeFile(eventId, uploadFile)
        self.assertEqual(r.status, 201) # CREATED

Brian Moe's avatar
Brian Moe committed
277 278 279 280 281 282 283 284 285 286
    def test_unicode_param(self):
        """
        Test workaround for Python bug
        http://bugs.python.org/issue11898
        Raises exception if workaround fails.
        """
        uploadFile = os.path.join(testdatadir, "upload.data.gz")
        r = gracedb.writeFile(eventId, uploadFile)
        self.assertEqual(r.status, 201) # CREATED

287 288 289
    def test_logger(self):
        import logging
        import ligo.gracedb.rest
290
        import ligo.gracedb.logging
291 292 293 294 295 296 297 298
     
        logging.basicConfig()
        log = logging.getLogger('testing')
        log.propagate = False   # Don't write to console

        #gracedb = ligo.gracedb.rest.GraceDb()
        graceid = eventId
     
299
        log.addHandler(ligo.gracedb.logging.GraceDbLogHandler(gracedb, graceid))
300 301 302 303 304 305

        message = "Message is {0}".format(random.random())
        log.warn(message)

        event_logs = gracedb.logs(graceid).read()
        self.assertTrue(message in event_logs)
306

307 308 309 310 311 312 313 314 315
    def test_issue717(self):
        # non-backwards-compatibility of cli.Client import.
        # import and use should not cause an import error.
        from ligo import gracedb
        gracedb.Client
        gracedb.ProxyHTTPConnection
        gracedb.error
        gracedb.ProxyHTTPSConnection

316 317 318
    def test_gittag(self):
        # try to make sure GIT_TAG is set properly.
        import errno
319
        version = "1.20"
320 321 322
        try:
            # If we are in the source dir (setup.py is available)
            # make sure the version above agrees.
323 324 325 326
            if os.path.exists("setup.py"):
                setup_file = open("setup.py", 'r')
            else:
                setup_file = open("../../../setup.py", 'r')
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
            v = ""
            for line in setup_file:
                if line.startswith("version"):
                    v = line.split('"')[1]
                    break
            self.assertEqual(v, version)
        except IOError, e:
            if e.errno != errno.ENOENT:
                raise

        # GIT_TAG should look like "gracedb-VERSION-PKG"
        # and VERSION should == version from above.

        from ligo.gracedb import GIT_TAG as package_tag
        package_tag = package_tag.split('-')[1]
        self.assertTrue(package_tag.startswith(v))

        from ligo.gracedb.cli import GIT_TAG as cli_tag
        cli_tag = cli_tag.split('-')[1]
        self.assertTrue(cli_tag.startswith(v))

        self.assertEqual(cli_tag, package_tag)

350 351 352 353 354 355 356 357 358 359 360
if __name__ == "__main__":

    global gracedb, testdatadir, createdEvent, eventId

#   Hacky "global" fixture.
#   Do not want to create a millions events
#   in order to test out event-updating features,
#   which is what a normal test case setUp() would do.

    testdatadir = os.path.join(os.path.dirname(__file__), "data")

361
    service = os.environ.get('TEST_SERVICE', TEST_SERVICE)
362
    sp_session_endpoint = os.environ.get('TEST_SP_SESSION_ENDPOINT', TEST_SP_SESSION_ENDPOINT)
363 364
    testdatadir = os.environ.get('TEST_DATA_DIR', testdatadir)

365 366
    gracedb = GraceDb(service, sp_session_endpoint)
    gracedb.initialize()
367

368
    #gracedb = GraceDbBasic(service)
Brian Moe's avatar
Brian Moe committed
369
    print "Using service", service
370 371 372

    eventFile = os.path.join(testdatadir, "cbc-lm.xml")
    createdEvent = gracedb.createEvent(
373
            "Test", "gstlal", eventFile, "LowMass").json()
374 375 376
    eventId = createdEvent["graceid"]

    unittest.main()