def test_add_node_changes_hash(self): tree = SyncTree(**temp_info) root = tree.root old_root_hash = root.get_hash() root_child1 = tree.add_node(root, **temp_info2) new_root_hash = root.get_hash() self.assertTrue(TestNodeCore.check_sync_hash_old_new(old_root_hash, new_root_hash, False, False, False))
def test_tree_created(self): tree = SyncTree(**temp_info) self.assertIsInstance(tree, SyncTree) with self.assertRaises(RuntimeError): temp = SyncTree() self.assertEqual(tree.root, tree.root._parent) self.assertEqual(tree.root._pk, 0) self.assertEqual(tree.get_node(0), tree.root)
def test_tree_depth(self): tree = SyncTree(**temp_info) root = tree.root root_child1 = tree.add_node(root, **temp_info2) root_child2 = tree.add_node(root, **temp_info2) root_child1_child1 = tree.add_node(root_child1, **temp_info) self.assertEqual(root._depth, 0) self.assertEqual(root_child1._depth, 1) self.assertEqual(root_child2._depth, 1) self.assertEqual(root_child1_child1._depth, 2)
def basic_example_tree_create(self): self.tree = SyncTree(name="root_node") root = self.tree.root CSE = self.tree.add_node(root, category_name="CSE events") ECE = self.tree.add_node(root, category_name="ECE events") hackathon = self.tree.add_node(CSE, event_name="Esya Hackathon", hours=16) prosort = self.tree.add_node(CSE, event_name="Foobar Prosort", prizes=10000) hackOn = self.tree.add_node(CSE, event_name="HackOn", organisers=["a", "b"]) IOT_hackathon = self.tree.add_node(ECE, event_name="IOT", food=True) self.tree.refresh_tree()
def test_adding_node_adds_parent_to_update_queue(self): tree = SyncTree(**temp_info) root = tree.root tree.update_hash_queue.clear() node = tree.add_node(root, **temp_info2) self.assertIn(root._pk, tree.update_hash_queue) for x in range(10): child = tree.add_node(node, **temp_info) node = child tree.update_hash_queue.clear() new = tree.add_node(child, **temp_info2) self.assertIn(child._pk, tree.update_hash_queue)
def create_random_tree(number_of_nodes, initial_nodes_to_randomly_create_subtrees_under=None, parent_tree=None): init_given = initial_nodes_to_randomly_create_subtrees_under if (init_given is None and parent_tree is not None) or \ (init_given is not None and parent_tree is None): raise RuntimeError( "You should give parent_tree param if initial_nodes_to_randomly_create_subtrees_under is given") if parent_tree: parent_nodes_options = init_given else: parent_tree = SyncTree(**temp_info) parent_nodes_options = [parent_tree.root] for x in xrange(number_of_nodes - 1): # subtract root parent = choice(parent_nodes_options) node = parent_tree.add_node(parent, **temp_info2) parent_nodes_options.append(node) return parent_tree
class Example(object): def __init__(self): self.app = Flask(__name__) self.app.debug = True self.basic_example_tree_create() self.handler = Handler(self.tree) self.set_up() def basic_example_tree_create(self): self.tree = SyncTree(name="root_node") root = self.tree.root CSE = self.tree.add_node(root, category_name="CSE events") ECE = self.tree.add_node(root, category_name="ECE events") hackathon = self.tree.add_node(CSE, event_name="Esya Hackathon", hours=16) prosort = self.tree.add_node(CSE, event_name="Foobar Prosort", prizes=10000) hackOn = self.tree.add_node(CSE, event_name="HackOn", organisers=["a", "b"]) IOT_hackathon = self.tree.add_node(ECE, event_name="IOT", food=True) self.tree.refresh_tree() def set_up(self): @self.app.route('/api/sync/node') def end_point(): request_type = request.args.get('type', 'check') handle_request = {'check': self.handler.check, 'fetch': self.handler.fetch, 'get_parents': self.handler.get_parents} if request_type not in handle_request: return jsonify(success=False, error_message="Unknown API call type.") return handle_request[request_type](request) @self.app.route('/api/sync') def refresh_point(): DEFAULT_STARTING_TIME = 0 try: client_time = float(request.args.get( 'updated_time', DEFAULT_STARTING_TIME)) except ValueError: client_time = DEFAULT_STARTING_TIME nodes = self.tree.get_nodes_after_time(client_time) return jsonify(success=True, data={node._pk: { "hash": node.get_sync_hash(), "updated_time": node.get_update_time()} for node in nodes})
def test_setting_and_getting_node(self): tree = SyncTree(**temp_info) root = tree.root root_child1 = tree.add_node(root, **temp_info2) root_child2 = tree.add_node(root, **temp_info2) root_child1_child1 = tree.add_node(root_child1, **temp_info) self.assertEqual(tree.get_node(root_child2._pk), root_child2) self.assertEqual(tree.get_node(root_child1_child1._pk), root_child1_child1) self.assertSetEqual(tree.update_hash_queue, { root._pk, root_child1._pk, root_child2._pk, root_child1_child1._pk})
def test_refresh_hash_works(self): tree = SyncTree(**temp_info) root = tree.root root_child1 = tree.add_node(root, **temp_info2) root_child2 = tree.add_node(root, **temp_info2) root_child1_child1 = tree.add_node(root_child1, **temp_info) tree.refresh_tree() old_sync_hashes = {x: x.get_sync_hash() for x in tree._pk_to_node_mapper.values()} for x in sorted(tree._pk_to_node_mapper.values(), key=lambda x: x._depth, reverse=True): x._update_hash() new_sync_hashes = {x: x.get_sync_hash() for x in tree._pk_to_node_mapper.values()} self.assertDictEqual(old_sync_hashes, new_sync_hashes)
def test_get_nodes_after_time(self): now = time_now() tree = SyncTree(**temp_info) root = tree.root # pk 0 root_child1 = tree.add_node(root, **temp_info) # pk 1 root_child2 = tree.add_node(root, **temp_info) # pk 2 root_child1_child1 = tree.add_node(root_child1, **temp_info) # pk 3 root_child2_child1 = tree.add_node(root_child2, **temp_info) # pk 4 root_child2_child1_child1 = tree.add_node(root_child2_child1, **temp_info) # pk 5 set_all = set([root, root_child1, root_child2, root_child1_child1, root_child2_child1, root_child2_child1_child1]) empty = set() tree.refresh_tree() changed_nodes = tree.get_nodes_after_time(now) self.assertSetEqual(changed_nodes, set_all) now = time_now() changed_nodes = tree.get_nodes_after_time(now) self.assertSetEqual(changed_nodes, empty) root_child1_child1.abc = "asg" tree.refresh_tree() changed_nodes = tree.get_nodes_after_time(now) self.assertSetEqual(changed_nodes, set([root_child1_child1, root_child1, root])) root.abd = "asg" tree.refresh_tree() changed_nodes = tree.get_nodes_after_time(now) self.assertSetEqual(changed_nodes, set([root_child1_child1, root_child1, root])) now = time_now() changed_nodes = tree.get_nodes_after_time(now) self.assertSetEqual(changed_nodes, empty) root_child2_child1_child1.abc = "def" root_child1.abc = "def" tree.refresh_tree() self.assertEqual(tree.get_nodes_after_time(now), set([root, root_child1, root_child2, root_child2_child1, root_child2_child1_child1]))
def test_updated_time_gets_touched_on_adding_info(self): tree = SyncTree(**temp_info) root = tree.root # pk 0 tree.refresh_tree() old = root.get_update_time() tree.refresh_tree() # no change should not cause time updating new = root.get_update_time() self.assertEqual(old, new) root.abc = "Something" tree.refresh_tree() new = root.get_update_time() self.assertNotEqual(old, new) old = root.get_update_time() root_child1 = tree.add_node(root, **temp_info) # pk 1 root_child2 = tree.add_node(root, **temp_info) # pk 2 root_child1_child1 = tree.add_node(root_child1, **temp_info) # pk 3 root_child2_child1 = tree.add_node(root_child2, **temp_info) # pk 4 tree.refresh_tree() new = root.get_update_time() self.assertNotEqual(old, new) temp = tree.add_node(root_child1_child1, **temp_info) # pk5 old_times = [tree.get_node(x).get_update_time() for x in range(5)] tree.refresh_tree() new_times = [tree.get_node(x).get_update_time() for x in range(5)] self.assertEqual(map(lambda x, y: x == y, old_times, new_times),[ False, # update time of root should have changed False, # update time of root_child1 should have changed True, # update time of root_child2 should not have changed False, # update time of root_child1_child1 should have changed True, # update time of root_child2_child1 should not have changed ] ) self.assertTrue(TestSyncTreeCore.validate_last_updated_relationship(tree)) random_tree = TestSyncTreeCore.create_random_tree(1000) random_tree.refresh_tree() self.assertTrue(TestSyncTreeCore.validate_last_updated_relationship(random_tree))
def test_tree_refreshes_properly_on_adding_node_way_down(self): tree = SyncTree(**temp_info) root = tree.root # pk 0 root_child1 = tree.add_node(root, **temp_info) # pk 1 root_child2 = tree.add_node(root, **temp_info) # pk 2 root_child1_child1 = tree.add_node(root_child1, **temp_info) # pk 3 root_child2_child1 = tree.add_node(root_child2, **temp_info) # pk 4 tree.refresh_tree() old_sync_hashes = {x: tree.get_node(x).get_sync_hash() for x in range(5)} root_child1_child1_child1 = tree.add_node(root_child1_child1, **temp_info) tree.refresh_tree() new_sync_hashes = {x: tree.get_node(x).get_sync_hash() for x in range(5)} # root should have total hash and children hash changed self.assertTrue(TestNodeCore.check_sync_hash_old_new( old_sync_hashes[0], new_sync_hashes[0], False, True, False)) # root_child1 should have total hash and children hash changed self.assertTrue(TestNodeCore.check_sync_hash_old_new( old_sync_hashes[1], new_sync_hashes[1], False, True, False)) # root_child2 should have no hash change self.assertTrue(TestNodeCore.check_sync_hash_old_new( old_sync_hashes[2], new_sync_hashes[2], True, True, True)) # root_child1_child1 should have total hash and children hash changed self.assertTrue(TestNodeCore.check_sync_hash_old_new( old_sync_hashes[3], new_sync_hashes[3], False, True, False)) # root_child2_child1 should have no hash change self.assertTrue(TestNodeCore.check_sync_hash_old_new( old_sync_hashes[4], new_sync_hashes[4], True, True, True)) self.assertTrue(TestSyncTreeCore.validate_last_updated_relationship(tree))