~ubuntu-branches/ubuntu/trusty/desktopcouch/trusty

« back to all changes in this revision

Viewing changes to desktopcouch/records/tests/test_server.py

  • Committer: Ken VanDine
  • Date: 2010-09-28 15:53:39 UTC
  • mfrom: (30.1.1 d-0.6.9)
  • Revision ID: ken.vandine@canonical.com-20100928155339-acv35l2m5py9o5r6
Tags: 0.6.9-0ubuntu1
releasing version 0.6.9-0ubuntu1

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
"""testing database/contact.py module"""
21
21
import testtools
 
22
import os
 
23
import signal
 
24
import time
22
25
 
23
26
import desktopcouch.tests as test_environment
24
27
from desktopcouch.records.server import CouchDatabase
25
28
from desktopcouch.records.server_base import (
26
29
    row_is_deleted, NoSuchDatabase, FieldsConflict, ResourceConflict)
27
30
from desktopcouch.records.record import Record
 
31
from desktopcouch.stop_local_couchdb import stop_couchdb
 
32
from desktopcouch import find_pid
28
33
 
29
34
# pylint can't deal with failing imports even when they're handled
30
35
# pylint: disable-msg=F0401
53
58
        # Connect to CouchDB server
54
59
        self.dbname = self._testMethodName
55
60
        self.database = CouchDatabase(self.dbname, create=True,
56
 
                ctx=test_environment.test_context)
 
61
                ctx=self.get_test_context())
57
62
        #create some records to pull out and test
58
63
        self.database.put_record(Record({
59
64
            "key1_1": "val1_1", "key1_2": "val1_2", "key1_3": "val1_3",
67
72
 
68
73
    def tearDown(self):
69
74
        """tear down each test"""
 
75
        this_context = self.get_test_context()
 
76
        if this_context != test_environment.test_context:
 
77
            stop_couchdb(ctx=this_context)
70
78
        super(TestCouchDatabase, self).tearDown()
71
 
        del self.database._server[self.dbname]
 
79
 
 
80
    def get_test_context(self):
 
81
        return test_environment.test_context
 
82
 
 
83
    def maybe_die(self):
 
84
        pass
 
85
 
 
86
    def wait_until_server_dead(self, pid=None):
 
87
        if pid is not None:
 
88
            pid = find_pid(start_if_not_running=False, ctx=self.get_test_context())
 
89
        if pid is None:
 
90
            return
 
91
        while True:
 
92
            try:
 
93
                os.kill(pid, 0)  # Wait until exited
 
94
                time.sleep(0.1)
 
95
            except OSError:
 
96
                break
72
97
 
73
98
    def test_database_not_exists(self):
74
99
        self.assertRaises(
78
103
        """Test getting mutliple records by type"""
79
104
        records = self.database.get_records(
80
105
            record_type="test.com",create_view=True)
81
 
        self.assertEqual(3,len(records))
 
106
        self.maybe_die()  # should be able to survive couchdb death
 
107
        self.assertEqual(3, len(records))
82
108
 
83
109
    def test_get_record(self):
84
110
        """Test getting a record."""
85
111
        record = Record({'record_number': 0}, record_type="http://example.com/")
86
112
        record_id = self.database.put_record(record)
 
113
        self.maybe_die()  # should be able to survive couchdb death
87
114
        retrieved_record = self.database.get_record(record_id)
88
115
        self.assertEqual(0, retrieved_record['record_number'])
89
116
 
91
118
        """Test putting a record."""
92
119
        record = Record({'record_number': 0}, record_type="http://example.com/")
93
120
        record_id = self.database.put_record(record)
94
 
        retrieved_record = self.database._server[self.dbname][record_id]
 
121
        self.maybe_die()  # should be able to survive couchdb death
 
122
        retrieved_record = self.database.get_record(record_id)
95
123
        self.assertEqual(
96
124
            record['record_number'], retrieved_record['record_number'])
97
125
 
121
149
        record = Record({'record_number': 0}, record_type="http://example.com/")
122
150
        record_id = self.database.put_record(record)
123
151
        self.database.delete_record(record_id)
 
152
        ###self.maybe_die()  # should be able to survive couchdb death
124
153
        deleted_record = self.database._server[self.dbname][record_id]
 
154
        #deleted_record = self.database.get_record(record_id)
125
155
        self.assert_(deleted_record['application_annotations']['Ubuntu One'][
126
156
            'private_application_annotations']['deleted'])
127
157
 
154
184
        record = Record({'record_number': 0}, record_type="http://example.com/")
155
185
        record_id = self.database.put_record(record)
156
186
        self.database.delete_record(record_id)
 
187
        self.maybe_die()  # should be able to survive couchdb death
157
188
        retrieved_record = self.database.get_record(record_id)
158
189
        self.assertEqual(None, retrieved_record)
159
190
 
162
193
        record = Record({'record_number': 0}, record_type="http://example.com/")
163
194
        self.assert_(not self.database.record_exists("ThisMustNotExist"))
164
195
        record_id = self.database.put_record(record)
 
196
        self.maybe_die()  # should be able to survive couchdb death
165
197
        self.assert_(self.database.record_exists(record_id))
166
198
        self.database.delete_record(record_id)
167
199
        self.assert_(not self.database.record_exists(record_id))
171
203
        dictionary = {'record_number': 0, 'field1': 1, 'field2': 2}
172
204
        record = Record(dictionary, record_type="http://example.com/")
173
205
        record_id = self.database.put_record(record)
 
206
        self.maybe_die()  # should be able to survive couchdb death
174
207
        # manipulate the database 'out of view'
175
208
        non_working_copy = self.database.get_record(record_id)
176
209
        non_working_copy['field2'] = 22
177
210
        non_working_copy['field3'] = 3
178
211
        self.database.put_record(non_working_copy)
179
212
        self.database.update_fields(record_id, {'field1': 11})
 
213
        self.maybe_die()  # should be able to survive couchdb death
180
214
        working_copy = self.database.get_record(record_id)
181
215
        self.assertEqual(0, working_copy['record_number'])
182
216
        self.assertEqual(11, working_copy['field1'])
200
234
        self.assertRaises(
201
235
            KeyError, self.database.delete_view, view2_name, design_doc)
202
236
        self.database.add_view(view1_name, map_js, reduce_js, design_doc)
 
237
        self.maybe_die()  # should be able to survive couchdb death
203
238
        self.database.add_view(view2_name, map_js, reduce_js, design_doc)
204
239
        self.database.delete_view(view1_name, design_doc)
205
240
        self.assertRaises(
206
241
            KeyError, self.database.delete_view, view1_name, design_doc)
 
242
        self.maybe_die()  # should be able to survive couchdb death
207
243
        self.database.delete_view(view2_name, design_doc)
208
244
        self.assertRaises(
209
245
            KeyError, self.database.delete_view, view2_name, design_doc)
237
273
            record_ids_we_care_about.remove(row.id)
238
274
            self.assertFalse(row_is_deleted(row))
239
275
 
 
276
        self.maybe_die()  # should be able to survive couchdb death
240
277
        self.assertTrue(len(record_ids_we_care_about) == 0, "expected zero")
241
278
 
242
279
        self.assertRaises(KeyError, self.database.get_records,
250
287
        map_js = """function(doc) { emit(doc._id, null) }"""
251
288
        self.database.add_view(view_name, map_js, None, design_doc)
252
289
 
 
290
        self.maybe_die()  # should be able to survive couchdb death
253
291
        self.assertEqual(self.database.list_views(design_doc), [view_name])
254
292
        self.database.delete_view(view_name, design_doc)
255
293
 
257
295
 
258
296
    def test_get_view_by_type_new_but_already(self):
259
297
        self.database.get_records(create_view=True)
 
298
        self.maybe_die()  # should be able to survive couchdb death
260
299
        self.database.get_records(create_view=True)
261
300
        # No exceptions on second run?  Yay.
262
301
 
263
302
    def test_get_view_by_type_createxcl_fail(self):
264
303
        self.database.get_records(create_view=True)
 
304
        self.maybe_die()  # should be able to survive couchdb death
265
305
        self.assertRaises(KeyError, self.database.get_records, create_view=None)
266
306
 
267
307
    def test_get_changes(self):
321
361
        # Ensure time is same.
322
362
        self.assertEqual(saved_time, self.database._changes_last_used)
323
363
 
 
364
        ###self.maybe_die()  # should be able to survive couchdb death
 
365
 
324
366
        # Next time we run, we get the same event again.
325
367
        # Consume queued changes.
326
368
        count = self.database.report_changes(rep)
370
412
        constructed_record.attach(content, "nu/mbe/rs", "text/plain")
371
413
        constructed_record.attach("string", "another document", "text/plain")
372
414
 
 
415
        ###self.maybe_die()  # should be able to survive couchdb death
373
416
        constructed_record.attach("XXXXXXXXX", "never used", "text/plain")
374
417
        constructed_record.detach("never used")  # detach works before commit.
375
418
 
382
425
        self.assertRaises(KeyError, constructed_record.attach, content,
383
426
                "another document", "text/x-rst")
384
427
 
 
428
        ###self.maybe_die()  # should be able to survive couchdb death
385
429
        record_id = self.database.put_record(constructed_record)
386
430
        retrieved_record = self.database.get_record(record_id)
387
431
 
402
446
        # get new
403
447
        retrieved_record = self.database.get_record(record_id)
404
448
 
 
449
        ###self.maybe_die()  # should be able to survive couchdb death
405
450
        # We can get a list of attachments.
406
451
        self.assertEqual(set(retrieved_record.list_attachments()),
407
452
                set(["nu/mbe/rs", "Document"]))
424
469
        self.assertEqual(out_data, content.getvalue())
425
470
        self.assertEqual(out_content_type, "text/plain")
426
471
 
 
472
        ###self.maybe_die()  # should be able to survive couchdb death
427
473
        # Asking for a named document that does not exist causes KeyError.
428
474
        self.assertRaises(KeyError, retrieved_record.attachment_data,
429
475
                "NoExist")
454
500
        # ordinary requests are in key order
455
501
        self.assertEqual(data, sorted(data))
456
502
 
 
503
        self.maybe_die()  # should be able to survive couchdb death
457
504
        # now request descending order and confirm that it *is* descending
458
505
        descdata = [i.key for i in
459
506
            list(self.database.execute_view(view1_name, design_doc,
513
560
            self.fail()
514
561
        except FieldsConflict, e:
515
562
            self.assertEqual({('field1',): (22, 11)}, e.conflicts)
 
563
 
 
564
 
 
565
class TestServerDiesSegv(TestCouchDatabase):
 
566
    def get_test_context(self):
 
567
        try:
 
568
            return self.ctx
 
569
        except AttributeError:
 
570
            self.ctx = test_environment.create_new_test_environment()
 
571
            return self.ctx
 
572
 
 
573
    def maybe_die(self):
 
574
        self.database.ensure_full_commit()
 
575
        time.sleep(2)
 
576
        pid = find_pid(start_if_not_running=False, ctx=self.get_test_context())
 
577
        if pid is None:
 
578
            print "couchdb has already quit!  That's unexpected."
 
579
            return
 
580
        print "DIE, process", pid, "!"
 
581
        os.kill(pid, signal.SIGSEGV)
 
582
        self.wait_until_server_dead(pid=pid)
 
583
 
 
584
 
 
585
class TestServerDiesNormal(TestCouchDatabase):
 
586
    def get_test_context(self):
 
587
        try:
 
588
            return self.ctx
 
589
        except AttributeError:
 
590
            self.ctx = test_environment.create_new_test_environment()
 
591
            return self.ctx
 
592
 
 
593
    def maybe_die(self):
 
594
        self.database.ensure_full_commit()
 
595
        time.sleep(2)
 
596
        stop_couchdb(ctx=self.get_test_context())
 
597
        self.wait_until_server_dead()