This file is indexed.

/usr/share/pyshared/ZODB/tests/testfsoids.py is in python-zodb 1:3.9.7-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  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
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 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
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
##############################################################################
#
# Copyright (c) 2004 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

r"""
fsoids test, of the workhorse fsoids.Trace class
================================================

Let's get a path to work with first.

>>> path = 'Data.fs'

More imports.

>>> import ZODB
>>> from ZODB.FileStorage import FileStorage
>>> import transaction as txn
>>> from BTrees.OOBTree import OOBTree
>>> from ZODB.FileStorage.fsoids import Tracer  # we're testing this

Create an empty FileStorage.

>>> st = FileStorage(path)

There's not a lot interesting in an empty DB!

>>> t = Tracer(path)
>>> t.register_oids(0x123456)
>>> t.register_oids(1)
>>> t.register_oids(0)
>>> t.run()
>>> t.report()
oid 0x00 <unknown> 0 revisions
    this oid was not defined (no data record for it found)
oid 0x01 <unknown> 0 revisions
    this oid was not defined (no data record for it found)
oid 0x123456 <unknown> 0 revisions
    this oid was not defined (no data record for it found)

That didn't tell us much, but does show that the specified oids are sorted
into increasing order.

Create a root object and try again:

>>> db = ZODB.DB(st) # yes, that creates a root object!
>>> t = Tracer(path)
>>> t.register_oids(0, 1)
>>> t.run(); t.report() #doctest: +ELLIPSIS
oid 0x00 persistent.mapping.PersistentMapping 1 revision
    tid 0x... offset=4 ...
        tid user=''
        tid description='initial database creation'
        new revision persistent.mapping.PersistentMapping at 52
oid 0x01 <unknown> 0 revisions
    this oid was not defined (no data record for it found)

So we see oid 0 has been used in our one transaction, and that it was created
there, and is a PersistentMapping.  4 is the file offset to the start of the
transaction record, and 52 is the file offset to the start of the data record
for oid 0 within this transaction.  Because tids are timestamps too, the
"..." parts vary across runs.  The initial line for a tid actually looks like
this:

    tid 0x035748597843b877 offset=4 2004-08-20 20:41:28.187000

Let's add a BTree and try again:

>>> root = db.open().root()
>>> root['tree'] = OOBTree()
>>> txn.get().note('added an OOBTree')
>>> txn.get().commit()
>>> t = Tracer(path)
>>> t.register_oids(0, 1)
>>> t.run(); t.report() #doctest: +ELLIPSIS
oid 0x00 persistent.mapping.PersistentMapping 2 revisions
    tid 0x... offset=4 ...
        tid user=''
        tid description='initial database creation'
        new revision persistent.mapping.PersistentMapping at 52
    tid 0x... offset=162 ...
        tid user=''
        tid description='added an OOBTree'
        new revision persistent.mapping.PersistentMapping at 201
        references 0x01 BTrees.OOBTree.OOBTree at 201
oid 0x01 BTrees.OOBTree.OOBTree 1 revision
    tid 0x... offset=162 ...
        tid user=''
        tid description='added an OOBTree'
        new revision BTrees.OOBTree.OOBTree at 350
        referenced by 0x00 persistent.mapping.PersistentMapping at 201

So there are two revisions of oid 0 now, and the second references oid 1.

One more, storing a reference in the BTree back to the root object:

>>> tree = root['tree']
>>> tree['root'] = root
>>> txn.get().note('circling back to the root')
>>> txn.get().commit()
>>> t = Tracer(path)
>>> t.register_oids(0, 1, 2)
>>> t.run(); t.report() #doctest: +ELLIPSIS
oid 0x00 persistent.mapping.PersistentMapping 2 revisions
    tid 0x... offset=4 ...
        tid user=''
        tid description='initial database creation'
        new revision persistent.mapping.PersistentMapping at 52
    tid 0x... offset=162 ...
        tid user=''
        tid description='added an OOBTree'
        new revision persistent.mapping.PersistentMapping at 201
        references 0x01 BTrees.OOBTree.OOBTree at 201
    tid 0x... offset=429 ...
        tid user=''
        tid description='circling back to the root'
        referenced by 0x01 BTrees.OOBTree.OOBTree at 477
oid 0x01 BTrees.OOBTree.OOBTree 2 revisions
    tid 0x... offset=162 ...
        tid user=''
        tid description='added an OOBTree'
        new revision BTrees.OOBTree.OOBTree at 350
        referenced by 0x00 persistent.mapping.PersistentMapping at 201
    tid 0x... offset=429 ...
        tid user=''
        tid description='circling back to the root'
        new revision BTrees.OOBTree.OOBTree at 477
        references 0x00 persistent.mapping.PersistentMapping at 477
oid 0x02 <unknown> 0 revisions
    this oid was not defined (no data record for it found)

Note that we didn't create any new object there (oid 2 is still unused), we
just made oid 1 refer to oid 0.  Therefore there's a new "new revision" line
in the output for oid 1.  Note that there's also new output for oid 0, even
though the root object didn't change:  we got new output for oid 0 because
it's a traced oid and the new transaction made a new reference *to* it.

Since the Trace constructor takes only one argument, the only sane thing
you can do to make it fail is to give it a path to a file that doesn't
exist:

>>> Tracer('/eiruowieuu/lsijflfjlsijflsdf/eurowiurowioeuri/908479287.fs')
Traceback (most recent call last):
  ...
ValueError: must specify an existing FileStorage

You get the same kind of exception if you pass it a path to an existing
directory (the path must be to a file, not a directory):

>>> import os
>>> Tracer(os.path.dirname(__file__))
Traceback (most recent call last):
  ...
ValueError: must specify an existing FileStorage


Clean up.
>>> st.close()
>>> st.cleanup() # remove .fs, .index, etc
"""

from zope.testing import doctest

def test_suite():
    return doctest.DocTestSuite()