def test_ids_traced_select_from_different_tables(self): self.env.create_nodes(3) clusters = db().query(models.Cluster).order_by("id").with_lockmode("update").all() nodes = db().query(models.Node).order_by("id").with_lockmode("update").all() nodes_lock = dd.find_lock(models.Node.__tablename__) clusters_lock = dd.find_lock(models.Cluster.__tablename__) self.assertEqual(nodes_lock.locked_ids, set(o.id for o in nodes)) self.assertEqual(clusters_lock.locked_ids, set(o.id for o in clusters))
def test_bulk_update_query_ids_traced(self): self.env.create_nodes(2) self.assertIsNone(dd.find_lock(models.Node.__tablename__, strict=False)) node = self.env.nodes[0] db().query(models.Node).filter(models.Node.id == node.id).update({"status": consts.NODE_STATUSES.error}) nodes_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(nodes_lock) self.assertEqual(nodes_lock.locked_ids, set([node.id]))
def test_ids_traced_select_from_different_tables(self): self.env.create_nodes(3) clusters = db().query(models.Cluster).order_by('id').\ with_lockmode('update').all() nodes = db().query(models.Node).order_by('id').\ with_lockmode('update').all() nodes_lock = dd.find_lock(models.Node.__tablename__) clusters_lock = dd.find_lock(models.Cluster.__tablename__) self.assertEqual(nodes_lock.locked_ids, set(o.id for o in nodes)) self.assertEqual(clusters_lock.locked_ids, set(o.id for o in clusters))
def test_bulk_update_query_ids_traced(self): self.env.create_nodes(2) self.assertIsNone(dd.find_lock( models.Node.__tablename__, strict=False)) node = self.env.nodes[0] db().query(models.Node).filter(models.Node.id == node.id).\ update({'status': consts.NODE_STATUSES.error}) nodes_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(nodes_lock) self.assertEqual(nodes_lock.locked_ids, set([node.id]))
def all(self): result = super(DeadlockDetectingQuery, self).all() if self._is_locked_for_update(): for table in self._get_tables(): lock = dd.find_lock(table) lock.add_ids(o.id for o in result) return result
def test_bulk_delete_query_ids_traced(self): self.env.create_nodes(2) node = self.env.nodes[0] db().query(models.Node).filter(models.Node.id == node.id).delete() node_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(node_lock) self.assertEqual(node_lock.locked_ids, set([node.id]))
def test_locking_already_locked_objects(self): self.env.create_nodes(2) nodes = db().query(models.Node).order_by("id").with_lockmode("update").all() lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(lock.locked_ids, set(o.id for o in nodes)) db().query(models.Node).with_lockmode("update").get(nodes[0].id) self.assertEqual(lock.locked_ids, set(o.id for o in nodes))
def test_id_traced_on_object_deletion(self): self.env.create_nodes(2) node = self.env.nodes[0] node_id = node.id db().delete(node) node_lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(node_lock.locked_ids, set([node_id]))
def test_locking_already_locked_objects(self): self.env.create_nodes(2) nodes = db().query(models.Node).order_by('id').\ with_lockmode('update').all() lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(lock.locked_ids, set(o.id for o in nodes)) db().query(models.Node).with_lockmode('update').get(nodes[0].id) self.assertEqual(lock.locked_ids, set(o.id for o in nodes))
def test_bulk_delete_query_ids_traced(self): self.env.create_nodes(2) node = self.env.nodes[0] db().query(models.Node).filter(models.Node.id == node.id).\ delete() node_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(node_lock) self.assertEqual(node_lock.locked_ids, set([node.id]))
def test_id_traced_on_updating_object(self): cluster = self.env.create_cluster() self.env.create_nodes(2) self.env.create_cluster() self.assertGreater(len(self.env.clusters), 1) # Updating cluster cluster.status = consts.CLUSTER_STATUSES.error # Checking locked id trace cluster_lock = dd.find_lock(models.Cluster.__tablename__) self.assertEqual(cluster_lock.locked_ids, set([cluster.id])) # Updating nodes nodes = db().query(models.Node).order_by("id").all() for node in nodes: node.status = consts.NODE_STATUSES.error # Checking locked ids trace node_lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(node_lock.locked_ids, set(o.id for o in nodes))
def test_id_traced_on_updating_object(self): cluster = self.env.create_cluster() self.env.create_nodes(2) self.env.create_cluster() self.assertGreater(len(self.env.clusters), 1) # Updating cluster cluster.status = consts.CLUSTER_STATUSES.error # Checking locked id trace cluster_lock = dd.find_lock(models.Cluster.__tablename__) self.assertEqual(cluster_lock.locked_ids, set([cluster.id])) # Updating nodes nodes = db().query(models.Node).order_by('id').all() for node in nodes: node.status = consts.NODE_STATUSES.error # Checking locked ids trace node_lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(node_lock.locked_ids, set(o.id for o in nodes))
def test_id_traced_for_fetching_first(self): # Check lock registered for not found node node = db().query(models.Node).with_lockmode("update").order_by("id").first() self.assertIsNone(node) node_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(node_lock) self.assertEqual(set(), node_lock.locked_ids) # Check id traced self.env.create_nodes(2) node = db().query(models.Node).with_lockmode("update").order_by("id").first() self.assertIsNotNone(node) self.assertIn(node.id, node_lock.locked_ids)
def test_id_traced_in_get(self): # Check lock registered for not found node node = db().query(models.Node).with_lockmode("update").get(0) self.assertIsNone(node) nodes_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(nodes_lock) self.assertEqual(set(), nodes_lock.locked_ids) # Check id traced self.env.create_nodes(2) # Locking clusters db().query(models.Cluster).with_lockmode("update") # Locking nodes nodes = db().query(models.Node).order_by("id").all() # Locking in ASC order is ok for node in nodes: db().query(models.Node).with_lockmode("update").get(node.id) nodes_lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(nodes_lock.locked_ids, set(o.id for o in nodes))
def test_id_traced_in_get(self): # Check lock registered for not found node node = db().query(models.Node).with_lockmode('update').get(0) self.assertIsNone(node) nodes_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(nodes_lock) self.assertEqual(set(), nodes_lock.locked_ids) # Check id traced self.env.create_nodes(2) # Locking clusters db().query(models.Cluster).with_lockmode('update') # Locking nodes nodes = db().query(models.Node).order_by('id').all() # Locking in ASC order is ok for node in nodes: db().query(models.Node).with_lockmode('update').get(node.id) nodes_lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(nodes_lock.locked_ids, set(o.id for o in nodes))
def test_id_traced_for_fetching_first(self): # Check lock registered for not found node node = db().query(models.Node).with_lockmode('update').\ order_by('id').first() self.assertIsNone(node) node_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(node_lock) self.assertEqual(set(), node_lock.locked_ids) # Check id traced self.env.create_nodes(2) node = db().query(models.Node).with_lockmode('update').\ order_by('id').first() self.assertIsNotNone(node) self.assertIn(node.id, node_lock.locked_ids)
def test_deletion_with_non_last_lock_failed(self): old_cluster = self.env.create_cluster() self.env.create_nodes(2) new_cluster = self.env.create_cluster() # Locking clusters and nodes db().query(models.Cluster).with_lockmode("update").get(old_cluster.id) db().query(models.Node).with_lockmode("update").order_by("id").all() # Trying to delete not locked cluster with non last lock last_lock = dd.context.locks[-1] cluster_lock = dd.find_lock(models.Cluster.__tablename__) self.assertNotEqual(cluster_lock, last_lock) with self.assertRaises(dd.TablesLockingOrderViolation): db().delete(new_cluster)
def test_id_traced_for_fetching_one(self): # Check lock registered for not found node with self.assertRaises(exc.NoResultFound): db().query(models.Node).with_lockmode("update").filter(models.Node.id == 0).one() # We have registered lock due to processing with_lockmode node_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(node_lock) self.assertEqual(set(), node_lock.locked_ids) # Check id traced self.env.create_nodes(2) node = self.env.nodes[0] node = db().query(models.Node).with_lockmode("update").filter(models.Node.id == node.id).one() self.assertIsNotNone(node) self.assertIn(node.id, node_lock.locked_ids)
def test_id_traced_for_fetching_one(self): # Check lock registered for not found node with self.assertRaises(exc.NoResultFound): db().query(models.Node).with_lockmode('update').\ filter(models.Node.id == 0).one() # We have registered lock due to processing with_lockmode node_lock = dd.find_lock(models.Node.__tablename__, strict=False) self.assertIsNotNone(node_lock) self.assertEqual(set(), node_lock.locked_ids) # Check id traced self.env.create_nodes(2) node = self.env.nodes[0] node = db().query(models.Node).with_lockmode('update').\ filter(models.Node.id == node.id).one() self.assertIsNotNone(node) self.assertIn(node.id, node_lock.locked_ids)
def test_deletion_with_non_last_lock_failed(self): old_cluster = self.env.create_cluster() self.env.create_nodes(2) new_cluster = self.env.create_cluster() # Locking clusters and nodes db().query(models.Cluster).with_lockmode('update').\ get(old_cluster.id) db().query(models.Node).with_lockmode('update').\ order_by('id').all() # Trying to delete not locked cluster with non last lock last_lock = dd.context.locks[-1] cluster_lock = dd.find_lock(models.Cluster.__tablename__) self.assertNotEqual(cluster_lock, last_lock) with self.assertRaises(dd.TablesLockingOrderViolation): db().delete(new_cluster)
def test_lock_ids_in_non_last_lock_failed(self): cluster = self.env.create_cluster() self.env.create_nodes(2) another_cluster = self.env.create_cluster() self.assertGreater(len(self.env.clusters), 1) # Tracing cluster modification cluster.status = consts.CLUSTER_STATUSES.error cluster_lock = dd.find_lock(models.Cluster.__tablename__) self.assertEqual(cluster_lock.locked_ids, set([cluster.id])) # Tracing nodes modification db().query(models.Node).with_lockmode('update').order_by('id').all() # Trying to lock ids in non last lock last_lock = dd.context.locks[-1] self.assertNotEqual(cluster_lock, last_lock) with self.assertRaises(dd.TablesLockingOrderViolation): another_cluster.status = consts.CLUSTER_STATUSES.error
def test_lock_ids_in_non_last_lock_failed(self): cluster = self.env.create_cluster() self.env.create_nodes(2) another_cluster = self.env.create_cluster() self.assertGreater(len(self.env.clusters), 1) # Tracing cluster modification cluster.status = consts.CLUSTER_STATUSES.error cluster_lock = dd.find_lock(models.Cluster.__tablename__) self.assertEqual(cluster_lock.locked_ids, set([cluster.id])) # Tracing nodes modification db().query(models.Node).with_lockmode("update").order_by("id").all() # Trying to lock ids in non last lock last_lock = dd.context.locks[-1] self.assertNotEqual(cluster_lock, last_lock) with self.assertRaises(dd.TablesLockingOrderViolation): another_cluster.status = consts.CLUSTER_STATUSES.error
def test_find_lock(self): self.assertIsNone(dd.find_lock('xxx', strict=False)) db().query(models.Release).with_lockmode('update').all() lock = dd.find_lock(models.Release.__tablename__, strict=True) self.assertIsNotNone(lock) self.assertEqual(models.Release.__tablename__, lock.table)
def _trace_single_row(self, row): if self._is_locked_for_update(): for table in self._get_tables(): lock = dd.find_lock(table) if row is not None: lock.add_ids((row.id,))
def test_ids_traced_select_from_single_table(self): self.env.create_nodes(2) nodes = db().query(models.Node).order_by('id').\ with_lockmode('update').all() lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(lock.locked_ids, set(o.id for o in nodes))
def _trace_single_row(self, row): if self._is_locked_for_update(): for table in self._get_tables(): lock = dd.find_lock(table) if row is not None: lock.add_ids((row.id, ))
def test_find_lock(self): self.assertIsNone(dd.find_lock("xxx", strict=False)) db().query(models.Release).with_lockmode("update").all() lock = dd.find_lock(models.Release.__tablename__, strict=True) self.assertIsNotNone(lock) self.assertEqual(models.Release.__tablename__, lock.table)
def test_ids_traced_select_from_single_table(self): self.env.create_nodes(2) nodes = db().query(models.Node).order_by("id").with_lockmode("update").all() lock = dd.find_lock(models.Node.__tablename__) self.assertEqual(lock.locked_ids, set(o.id for o in nodes))