def test_createAttachedStoreIndexes(self): """ Indexes created by the insertion of the first item of a type into a store are created in the database which backs that store even if that store is attached to another store backed by a different database. """ secondaryPath = self.mktemp() main = store.Store() secondary = store.Store(secondaryPath, parent=main, idInParent=23) before = secondary._loadExistingIndexes() secondary.attachToParent() TestItem(store=secondary) # Close it to detach from the parent. Detach from the parent so we can # re-open and hopefully avoid accidentally getting any results polluted # by the parent store (shouldn't happen, because the above test, # test_loadExistingAttachedStoreIndexes, makes sure we can inspect # indexes without worrying about an attached parent, but I'm being # paranoid). secondary.close() del secondary secondary = store.Store(secondaryPath, parent=main, idInParent=23) after = secondary._loadExistingIndexes() self.assertEqual( after - before, set([ secondary._indexNameOf(TestItem, ['foo']), secondary._indexNameOf(TestItem, ['other']), secondary._indexNameOf(TestItem, ['myStore']), secondary._indexNameOf(TestItem, ['bar', 'baz']) ]))
def test_inMemorySchemaCacheReset(self): """ The global in-memory table schema cache should not change the behavior of consistency checking with respect to the redefinition of in-memory schemas. This test is verifying the behavior which is granted by the use of a WeakKeyDictionary for _inMemorySchemaCache. If that cache kept strong references to item types or used a (typeName, schemaVersion) key, either the second C{SoonToChange} class definition in this method would fail or the schema defined by the first C{SoonToChange} class would be used, even after it should have been replaced by the second definition. """ class SoonToChange(item.Item): attribute = attributes.integer() dbpath = self.mktemp() s = store.Store(dbpath) SoonToChange(store=s) s.close() # This causes a Store._checkTypeSchemaConsistency to cache # SoonToChange. s = store.Store(dbpath) s.close() del SoonToChange, s class SoonToChange(item.Item): attribute = attributes.boolean() self.assertRaises(RuntimeError, store.Store, dbpath)
def testNoCrossStoreRefs(self): s1 = store.Store() s2 = store.Store() t1 = TestItem(store=s1) self.assertRaises(errors.NoCrossStoreReferences, TestItem, store=s2, other=t1) t2 = TestItem(store=s2) self.assertRaises(errors.NoCrossStoreReferences, setattr, t2, 'other', t1) self.assertRaises(errors.NoCrossStoreReferences, setattr, t2, 'other', s1) t3 = TestItem(other=t1) self.assertRaises(errors.NoCrossStoreReferences, setattr, t3, 'store', s2) t3.store = s1 self.assertEquals(list(s1.query(TestItem)), [t1, t3])
def testTableCreation(self): storedir = self.mktemp() s1 = store.Store(storedir) self.assertRaises(ZeroDivisionError, s1.transact, setup, s1) s1.close() s2 = store.Store(storedir) self.assertRaises(ZeroDivisionError, s2.transact, setup, s2) s2.close()
def test_journalModeNone(self): """ Passing a journalling mode of C{None} sets no mode. """ dbdir = filepath.FilePath(self.mktemp()) s = store.Store(dbdir, journalMode=u'WAL') s.close() s = store.Store(dbdir, journalMode=None) self.assertEquals(s.querySchemaSQL('PRAGMA *DATABASE*.journal_mode'), [(u'wal', )])
def test_revertedTableCreation(self): """ When tables are created in a transaction which is reverted, they should persist in neither the SQL store nor the in-memory schema representation. """ storedir = self.mktemp() s1 = store.Store(storedir) self.assertRaises(SomeError, s1.transact, createAndRaise, s1) self.assertNotIn(A, s1.typeToTableNameCache) s1.close() s2 = store.Store(storedir) self.assertNotIn(A, s2.typeToTableNameCache)
def test_committedTableCreation(self): """ When tables are created in a transaction which is committed, they should persist in both Axiom's in-memory schema representation and within the on-disk SQL store. """ storedir = filepath.FilePath(self.mktemp()) s1 = store.Store(storedir) s1.transact(A, store=s1) self.assertIn(A, s1.typeToTableNameCache) s1.close() s2 = store.Store(storedir) self.assertIn(A, s2.typeToTableNameCache) s2.close()
def testNewItemType(self): """ Creating the first instance of a of an Item subclass changes the underlying database schema as well as some Store-private state which tracks that schema. Test to make sure that creating the first instance of an Item subclass in one store is reflected in a second store. """ dbdir = filepath.FilePath(self.mktemp()) firstStore = store.Store(dbdir) secondStore = store.Store(dbdir) ConcurrentItemA(store=firstStore) self.assertEquals(secondStore.query(ConcurrentItemA).count(), 1)
def test_loadExistingAttachedStoreIndexes(self): """ If a store is attached to its parent, L{Store._loadExistingIndexes} returns just the indexes which exist in the child store. """ secondaryPath = self.mktemp() main = store.Store() secondary = store.Store(secondaryPath, parent=main, idInParent=17) TestItem(store=secondary) before = secondary._loadExistingIndexes() secondary.attachToParent() after = secondary._loadExistingIndexes() self.assertEqual(before, after)
def test_axiomaticUpgradePerformFails(self): """ If an exception occurs while upgrading items, L{Upgrade.postOptions} reports the item and schema version for which it occurred and returns without exception. """ choose(oldapp) swordID = oldapp.Sword(store=self.store, name='rapier', hurtfulness=3).storeID self.store.close() choose(brokenapp) self.store = store.Store(self.dbdir) cmd = Upgrade() cmd.parent = CommandStub(self.store, 'upgrade') result, output = callWithStdoutRedirect(cmd.parseOptions, ['--count', '100']) lines = output.getvalue().splitlines() # Ensure that the original error is output. self.assertEqual(lines[0], 'Upgrader error:') self.assertTrue(len(lines) > 2) oldType = oldapp.Sword newType = store._typeNameToMostRecentClass[oldType.typeName] msg = cmd.errorMessageFormat % (oldType.typeName, swordID, oldType.schemaVersion, newType.schemaVersion) self.assertTrue(lines[-1].startswith(msg))
def test_upgradeStoreRecursing(self): """ L{Upgrade} upgrades L{Item}s in substores. """ choose(oldapp) ss1 = SubStore.createNew(self.store, ['a']) ss2 = SubStore.createNew(self.store, ['b']) swordIDs = [(ss1.storeID, oldapp.Sword(store=ss1.open(), name='foo').storeID), (ss2.storeID, oldapp.Sword(store=ss2.open(), name='bar').storeID)] del ss1, ss2 self.store.close() choose(deleteswordapp) self.store = store.Store(self.dbdir) cmd = Upgrade() cmd.parent = CommandStub(self.store, 'upgrade') callWithStdoutRedirect(cmd.parseOptions, []) for (ssid, swordID) in swordIDs: self.assertRaises(KeyError, self.store.getItemByID(ssid).open().getItemByID, swordID)
def setUp(self): self.store = store.Store() self.containmentCore = objects.Thing(store=self.store, name=u"container") self.container = objects.Container.createFor(self.containmentCore, capacity=1) self.object = objects.Thing(store=self.store, name=u"object")
def test_axiomaticUpgradeExceptionBubbling(self): """ Exceptions encountered by L{Upgrade.upgradeStore} are handled and re-raised as L{errors.ItemUpgradeError} with attributes indicating which L{Item} was being upgraded when the exception occurred. """ choose(oldapp) swordID = oldapp.Sword(store=self.store, name='longsword', hurtfulness=4).storeID self.store.close() choose(brokenapp) self.store = store.Store(self.dbdir) cmd = Upgrade() cmd.parent = CommandStub(self.store, 'upgrade') cmd.count = 100 err = self.assertRaises(errors.ItemUpgradeError, callWithStdoutRedirect, cmd.upgradeStore, self.store) self.assertTrue( err.originalFailure.check(brokenapp.UpgradersAreBrokenHere)) oldType = item.declareLegacyItem(oldapp.Sword.typeName, oldapp.Sword.schemaVersion, {}) self.assertEqual(err.storeID, swordID) self.assertIdentical(err.oldType, oldType) self.assertIdentical(err.newType, brokenapp.Sword)
def setUp(self): self.clock = sip.clock = task.Clock() self.dbdir = self.mktemp() self.store = store.Store(self.dbdir) self.login = userbase.LoginSystem(store=self.store) installOn(self.login, self.store) account = self.login.addAccount('bob', 'proxy2.org', None) account2 = self.login.addAccount('alice', 'proxy1.org', None) us = self.us = account.avatars.open() installOn(FakeAvatar(store=us), us) us2 = self.us2 = account2.avatars.open() installOn(FakeAvatar(store=us2), us2) self.tq = TaskQueue(self.clock) self.uas = useragent.UserAgent.server(sip.IVoiceSystem(us), "10.0.0.2", FakeMediaController()) self.uas2 = useragent.UserAgent.server(sip.IVoiceSystem(us2), "10.0.0.1", FakeMediaController()) self.sip1 = sip.SIPTransport(self.uas, ["server.com"], 5060) self.sip1.startProtocol() self.sip2 = sip.SIPTransport(self.uas2, ["client.com"], 5060) self.sip2.startProtocol() self.svc = sipserver.SIPServer(store=self.store) self.svc.mediaController = FakeMediaController() portal = Portal(self.login, [self.login]) self.svc.dispatcher = sip.SIPDispatcher(portal, sip.Proxy(portal)) self.svc.transport = sip.SIPTransport(self.svc.dispatcher, sipserver.getHostnames(self.store), 5060) self.svc.dispatcher.start(self.svc.transport) dests = {('10.0.0.2', 5060): self.uas, ('10.0.0.1', 5060): self.uas2, ('127.0.0.1', 5060): self.svc} self.messages = [] self.sip1.sendMessage = lambda msg, dest: self.tq.addTask(dests[dest].transport.datagramReceived, str(msg.toString()), ("10.0.0.2", 5060)) self.sip2.sendMessage = lambda msg, dest: self.tq.addTask(dests[dest].transport.datagramReceived, str(msg.toString()), ("10.0.0.1", 5060)) self.svc.transport.sendMessage = lambda msg, dest: self.messages.append(msg) or self.tq.addTask(dests[dest].transport.datagramReceived, str(msg.toString()), ("127.0.0.1", 5060)) useragent.Dialog.genTag = lambda self: "314159"
def createStore(testCase): """ Create a database suitable for use by the L{MailTests} suite. @type testCase: L{MailTests} @rtype: L{axiom.store.Store} """ location = testCase.mktemp() s = store.Store(location) def initializeStore(): """ Install site requirements for the MTA tests and create several users which will be used as the origin and destination of various test messages. """ login = userbase.LoginSystem(store=s) installOn(login, s) for (localpart, domain, internal) in [ ('testuser', 'localhost', True), ('testuser', 'example.com', False), ('administrator', 'localhost', True)]: account = login.addAccount(localpart, domain, None, internal=internal) subStore = account.avatars.open() def endow(): installOn(Inbox(store=subStore), subStore) installOn(Composer(store=subStore), subStore) subStore.transact(endow) s.transact(initializeStore) return s
def testDontAllowNone(self): s = store.Store() def testDontAllowNone(): try: x = StricterItem(store=s) except TypeError: pass else: self.fail( "Creating a StricterItem without an aRef value should have failed" ) a = AttributefulItem(store=s) x = StricterItem(store=s, aRef=a) self.assertEquals(x.aRef, a) try: x.aRef = None except TypeError: pass else: self.fail( "Setting aRef to None on a StricterItem should have failed" ) s.transact(testDontAllowNone)
def testTypeToDatabaseNames(self): # The real purpose of this test is to have the new get*Name # methods explicitely called somewhere in the test suite. The # effect itself does not actually matter much. These functions # are proven right by the fact that item creation, querying # and update are working. # I think the following should be ok for anything that vaguely # ressembles SQL. s = store.Store() tn = s.getTableName(TestItem) assert tn.startswith(s.databaseName) cn = s.getColumnName(TestItem.foo) scn = s.getShortColumnName(TestItem.foo) assert len(tn) < len(cn) assert len(scn) < len(cn) assert cn.endswith(scn) assert cn.startswith(tn) icn = s.getColumnName(TestItem.storeID) sicn = s.getShortColumnName(TestItem.storeID) assert len(tn) < len(icn) assert len(sicn) < len(icn) assert icn.endswith(sicn) assert icn.startswith(tn)
def test_itemAddedStartsBatchProcess(self): """ If there are remote-style listeners for an item source, C{itemAdded} starts the batch process. This is not completely correct. There may be items to process remotely when the main process starts up, before any new items are added. This is simpler to implement, but it shouldn't be taken as a reason not to implement the actually correct solution. """ st = store.Store(self.mktemp()) svc = service.IService(st) svc.startService() self.addCleanup(svc.stopService) batchService = iaxiom.IBatchService(st) procType = batch.processor(TestWorkUnit) proc = procType(store=st) listener = WorkListener(store=st) proc.addReliableListener(listener, style=iaxiom.REMOTE) # Sanity check: addReliableListener should eventually also trigger a # batch process start if necessary. But we don't want to test that case # here, so make sure it's not happening. self.assertEqual(batchService.batchController.mode, 'stopped') # Now trigger it to start. proc.itemAdded() # It probably won't be ready by now, but who knows. self.assertIn(batchService.batchController.mode, ('starting', 'ready'))
def setUp(self): """ Set up a store with a location, a player and an observer. """ self.store = store.Store() self.location = objects.Thing(store=self.store, name=u"Test Location", description=u"Location for testing.", proper=True) locContainer = objects.Container.createFor(self.location, capacity=1000) self.world = ImaginaryWorld(store=self.store, origin=self.location) self.player = self.world.create(u"Test Player", gender=language.Gender.FEMALE) self.playerContainer = iimaginary.IContainer(self.player) self.playerWrapper = player.Player(self.player) self.playerWrapper.useColors = False locContainer.add(self.player) self.transport = StringTransport() self.playerWrapper.setProtocol(PlayerProtocol(self.transport)) self.observer = self.world.create(u"Observer Player", gender=language.Gender.FEMALE) self.observerWrapper = player.Player(self.observer) locContainer.add(self.observer) self.otransport = StringTransport() self.observerWrapper.setProtocol(PlayerProtocol(self.otransport)) # Clear the transport, since we don't care about the observer # arrival event. self.transport.clear()
def test_checkInconsistentTypeSchema(self): """ L{Store._checkTypeSchemaConsistency} raises L{RuntimeError} if the in memory schema of the type passed to it differs from the schema stored in the database for that type, either by including too few attributes, too many attributes, or the wrong type for one of the attributes. """ s = store.Store() schema = [(name, attr.sqltype, attr.indexed, attr, attr.doc) for (name, attr) in TestItem.getSchema()] # Test a missing attribute self.assertRaises( RuntimeError, s._checkTypeSchemaConsistency, TestItem, {(TestItem.typeName, TestItem.schemaVersion): schema[:-1]}) # And an extra attribute self.assertRaises(RuntimeError, s._checkTypeSchemaConsistency, TestItem, { (TestItem.typeName, TestItem.schemaVersion): schema + [schema[0]] }) # And the wrong type for one of the attributes self.assertRaises( RuntimeError, s._checkTypeSchemaConsistency, TestItem, { (TestItem.typeName, TestItem.schemaVersion): [(schema[0], 'VARCHAR(64) (this is made up)', schema[2], schema[3], schema[4])] + schema[1:] })
def testPolicy(self): """ Test that only internal or verified L{userbase.LoginMethod}s with protocol=email are considered candidates for from addresses """ s = store.Store(self.mktemp()) ls = userbase.LoginSystem(store=s) installOn(ls, s) acc = ls.addAccount('username', 'dom.ain', 'password', protocol=u'not email') ss = acc.avatars.open() # not verified or internal, should explode self.assertRaises(RuntimeError, lambda: smtpout._getFromAddressFromStore(ss)) # ANY_PROTOCOL acc.addLoginMethod(u'yeah', u'x.z', internal=True) # should work self.assertEquals('[email protected]', smtpout._getFromAddressFromStore(ss)) ss.findUnique( userbase.LoginMethod, userbase.LoginMethod.localpart == u'yeah').deleteFromStore() # external, verified acc.addLoginMethod(u'yeah', u'z.a', internal=False, verified=True) # should work self.assertEquals('[email protected]', smtpout._getFromAddressFromStore(ss))
def setUp(self): """ Set up a store with a location, a player and an observer. """ self.store = store.Store() locContainer = createLocation( self.store, u"Test Location", u"Location for testing.") self.location = locContainer.thing self.world = ImaginaryWorld(store=self.store, origin=self.location) self.player = self.world.create( u"Test Player", gender=self.genderForTest) self.playerContainer = iimaginary.IContainer(self.player) self.playerWrapper = player.Player(self.player) self.playerWrapper.useColors = False locContainer.add(self.player) self.transport = StringTransport() self.playerWrapper.setProtocol(PlayerProtocol(self.transport)) self.observer = self.world.create( u"Observer Player", gender=language.Gender.FEMALE) self.observerWrapper = player.Player(self.observer) locContainer.add(self.observer) self.otransport = StringTransport() self.observerWrapper.setProtocol(PlayerProtocol(self.otransport)) # Clear the transport, since we don't care about the observer # arrival event. self.transport.clear()
def testLoadUnimportedPlainItem(self): """ Test that an Item in the database can be loaded out of the database, even if the module defining its Python class has not been imported, as long as its class definition has not moved since it was added to the database. """ storePath = filepath.FilePath(self.mktemp()) st = store.Store(storePath) itemID = itemtest.PlainItem(store=st, plain=u'Hello, world!!!').storeID st.close() e = os.environ.copy() d = defer.Deferred() p = ProcessOutputCollector(d) try: reactor.spawnProcess(p, sys.executable, [ sys.executable, '-Wignore', itemtestmain.__file__.rstrip('co'), storePath.path, str(itemID) ], e) except NotImplementedError: raise unittest.SkipTest("Implement processes here") def cbOutput(output): self.assertEquals(''.join(output).strip(), 'Hello, world!!!') def ebBlah(err): log.err(err) self.fail(''.join(err.value.args[0].error)) return d.addCallbacks(cbOutput, ebBlah)
def setUp(self): self.storepath = self.mktemp() self.store = store.Store(self.storepath) self.headerRule = filter.HeaderRule(store=self.store, headerName=u"subject", value=u"subjval", operation=filter.EQUALS)
def main(storePath, itemID): assert 'axiom.test.itemtest' not in sys.modules, "Test is invalid." st = store.Store(storePath) item = st.getItemByID(itemID) print item.plain
def setUp(self): """ Make a store, an account/substore, an indexer, and call startService() on the superstore's IService so the batch process interactions that happen in fulltext.py work """ self.dbdir = self.mktemp() self.path = u'index' superstore = store.Store(self.dbdir) loginSystem = LoginSystem(store=superstore) installOn(loginSystem, superstore) account = loginSystem.addAccount(u'testuser', u'example.com', None) substore = account.avatars.open() self.store = substore self.indexer = self.createIndexer() self.svc = IService(superstore) self.svc.startService() # Make sure the indexer is actually available writer = self.openWriteIndex() writer.close()
def main(): s = store.Store("tags.axiom") c = tags.Catalog(store=s) objects = [] def createObjects(): for x in range(N): objects.append(TaggedObject(store=s)) s.transact(createObjects) def tagObjects(): for o in objects: for x in range(N): c.tag(o, str(x)) s.transact(tagObjects) def getTags(): for i in range(N): for o in objects: for t in c.tagsOf(o): pass benchmark.start() s.transact(getTags) benchmark.stop()
def test_storedCallbackNotOnLoad(self): """ Test that pulling an item out of a store does not invoke its stored callback again. """ st = store.Store() storeID = StoredNoticingItem(store=st).storeID self.assertEquals(st.getItemByID(storeID).storedCount, 1)
def test_differentStoreTableCreation(self): """ If two different stores are opened before a given table is created, and one creates it, this should be transparent to both item creation and queries made from either store. """ storedir = self.mktemp() s1 = store.Store(storedir) s2 = store.Store(storedir) a1 = A(store=s1) a2 = A(store=s2) self.assertEqual( list(s1.query(A, sort=A.storeID.ascending).getColumn("storeID")), [a1.storeID, a2.storeID]) self.assertEqual( list(s2.query(A, sort=A.storeID.ascending).getColumn("storeID")), [a1.storeID, a2.storeID])
def testDeleteThenLoad(self): st = store.Store() i = itemtest.PlainItem(store=st) oldStoreID = i.storeID self.assertEquals(st.getItemByID(oldStoreID, default=1234), i) i.deleteFromStore() self.assertEquals(st.getItemByID(oldStoreID + 100, default=1234), 1234) self.assertEquals(st.getItemByID(oldStoreID, default=1234), 1234)