def test_compatible(self): c1 = CompatibilityClosure() c2 = CompatibilityClosure() brl0 = BRLBlock('user/user/block/master') brl1 = BRLBlock('user/user/block2/master') v0 = BlockVersion(brl0, 0) v1 = BlockVersion(brl0, 1) v2 = BlockVersion(brl1, 0) v3 = BlockVersion(brl1, 1) cell_id1 = ID((0, 0, 0)) cell_id2 = ID((0, 0, 1)) content_id1 = ID((0, 0, 0)) content_id2 = ID((0, 0, 1)) c1.add_item((cell_id1, content_id1), cell_id1, v0, 'file1') c2.add_item((cell_id1, content_id1), cell_id1, v1, 'file1') self.assertEqual(0, c1.conflicts(c2)) self.assertEqual(0, c2.conflicts(c1)) c1.add_item((cell_id2, content_id2), cell_id2, v2, 'file2') c2.add_item((cell_id2, content_id2), cell_id2, v3, 'file2') self.assertEqual(0, c1.conflicts(c2)) self.assertEqual(0, c2.conflicts(c1))
def test_renames(self): publish_request = PublishRequest(BlockVersion(self.brl, -1)) publish_request.cells.append(SimpleCell('user/block/r1.h')) publish_request.contents['r1.h'] = Content(id_=None, load=None) publish_request.cells.append(SimpleCell('user/block/r2.h')) publish_request.contents['r2.h'] = Content(id_=None, load=None) publish_request.cells.append(SimpleCell('user/block/r3.h')) publish_request.contents['r3.h'] = Content(id_=None, load=None) publish_request.tag = STABLE self.block.add_publication(publish_request) publish_request = PublishRequest(BlockVersion(self.brl, 0)) publish_request.cells.append(SimpleCell('user/block/r11.h')) publish_request.deleted.append('r1.h') publish_request.renames = Renames( {CellName('r1.h'): CellName('r11.h')}) publish_request.tag = STABLE self.block.add_publication(publish_request) publish_request = PublishRequest(BlockVersion(self.brl, 1)) publish_request.cells.append(SimpleCell('user/block/r21.h')) publish_request.deleted.append('r2.h') publish_request.renames = Renames( {CellName('r2.h'): CellName('r21.h')}) publish_request.tag = STABLE self.block.add_publication(publish_request) self.assertEquals({}, self.block.get_renames(0, 0)) self.assertEquals({'r1.h': 'r11.h'}, self.block.get_renames(0, 1)) self.assertEquals({ 'r2.h': 'r21.h', 'r1.h': 'r11.h' }, self.block.get_renames(0, 2))
def test_interface(self): cell_id1 = ID((0, 0, 0)) content_id1 = ID((0, 0, 0)) cell_id2 = ID((0, 1, 0)) content_id2 = ID((0, 1, 0)) brl0 = BRLBlock('user/user/block/master') brl1 = BRLBlock('user/user/block2/master') v0 = BlockVersion(brl0, 0) v1 = BlockVersion(brl0, 1) v2 = BlockVersion(brl1, 0) c1 = CompatibilityClosure() c1.add_item((cell_id1, content_id1), cell_id1, v0, 'file1') self.assertEqual("{0:0:0: ((0:0:0, 0:0:0), user/block: 0, 'file1')}", str(c1)) # adding a compatible item is no problem c1.add_item((cell_id1, content_id1), cell_id1, v1, 'file1') self.assertEqual("{0:0:0: ((0:0:0, 0:0:0), user/block: 1, 'file1')}", str(c1)) c1.add_item((cell_id2, content_id2), cell_id2, v2, 'file2') self.assertIn("0:0:0: ((0:0:0, 0:0:0), user/block: 1, 'file1')", str(c1)) self.assertIn("0:1:0: ((0:1:0, 0:1:0), user/block2: 0, 'file2')", str(c1)) self.assertEqual({v0.block_name + 'file1', v2.block_name + 'file2'}, c1.block_cell_names) refs = References() refs[v1].add('file1') refs[v2].add('file2') self.assertEqual(refs, c1.references)
def select_version(hive_holder, biiapi, biiout, block_name, track, time, version_tag): dependencies = hive_holder.hive_dependencies.dep_graph.nodes dep_block_versions = {x.block_name: x for x in dependencies} existing_version = dep_block_versions.get(block_name) if existing_version: brl_block = block_name + track if track is not None else existing_version.block if time is None: if version_tag is not None: block_version = biiapi.get_version_by_tag( brl_block, version_tag) else: block_version = BlockVersion(brl_block, existing_version.time) else: block_version = BlockVersion(brl_block, time) if block_version != existing_version: biiout.warn( "You had in your dependencies %s, but opening %s instead" % (existing_version.to_pretty(), block_version.to_pretty())) else: # Not in dependencies brl_block = block_name + track if track is not None else block_name.default_block( ) if time is None: if version_tag is not None: block_version = biiapi.get_version_by_tag( brl_block, version_tag) else: # If its an unrelated block we get last version block_info = biiapi.get_block_info(brl_block) block_version = block_info.last_version else: block_version = BlockVersion(brl_block, time) return block_version
def _publishDependentCell(self, block_id): low, high = self._biigraph._get_range_block(block_id) count = 0 d = self.lbcn bcn = d[block_id] brl = self._getBlockBRL(bcn) for row in range(low, high + 1): r = SimpleCell(d[block_id]) r.root = ID((0, bcn.block_name[-1:], 0)) deps = DependencySet() dep_table = BlockVersionTable() for block in range(block_id): time = self._biigraph._get_dep_elem_offset(row, block) if time != -1: deps.add_implicit(d[block]) dep_table[d[block].block_name] = \ BlockVersion(self._getBlockBRL(d[block]), time) r.dependencies = deps pack = PublishRequest(BlockVersion(brl, count - 1)) pack.tag = STABLE count += 1 pack.cells.append(r) pack.contents[r.name.cell_name] = Content( id_=None, load=Blob('hola {0}'.format(r.name.cell_name))) pack.deptable = dep_table self.service.publish(pack)
def requirements_update_test(self): block_name = BlockName("user/block") text = "[requirements]\n # My comment\n" config = BiiConfig(text) self.assertEqual(config.dumps(), None) version = BlockVersion(block_name.default_block(), 0) config.requirements = BlockVersionTable([version]) dumped = config.dumps() self.assertEqual(dumped, "[requirements]\n\t user/block: 0\n\n") # Dump again, no changes self.assertEqual(config.dumps(), None) config2 = BiiConfig(dumped) self.assertEqual(config2.requirements, config.requirements) block_name2 = BlockName("auser2/block2") version2 = BlockVersion(block_name2.default_block(), 2) config.requirements = BlockVersionTable([version, version2]) dumped = config.dumps() self.assertEqual( dumped, "[requirements]\n" "\t auser2/block2: 2\n\t user/block: 0\n\n") # Dump again, no changes self.assertEqual(config.dumps(), None) config3 = BiiConfig(dumped) self.assertEqual(config3.requirements, config.requirements)
def _virtual_setup(self): ref_translator = Mock() depA = BlockVersion(BRLBlock('user/user/blockA/branch'), 4) depB = BlockVersion(BRLBlock('user/user/blockB/branch'), 2) baseC = BlockVersion(BRLBlock('user/user/blockC/branch'), 3) full_graph = BlockVersionGraph() full_graph.add_nodes([baseC, depA, depB]) full_graph.add_edge(baseC, depA) full_graph.add_edge(baseC, depB) def res_method(*args): c_virtual_leaves = [BlockCellName('user/blockC/win/c.h'), BlockCellName('user/blockC/nix/c.h')] c_win_deps = [BlockCellName('user/blockA/a.h')] c_nix_deps = [BlockCellName('user/blockB/b.h')] result = ReferencedResources() for ref in args[0].explode(): result[ref.block_version][ref.ref] = \ {Reference(depA, 'a.h'): ((0, 0), 0, []), Reference(depB, 'b.h'): ((1, 1), 1, []), Reference(baseC, 'c.h'): ((2, 2), 2, c_virtual_leaves), Reference(baseC, 'win/c.h'): ((3, 3), 3, c_win_deps), Reference(baseC, 'nix/c.h'): ((4, 4), 4, c_nix_deps)}[ref] return result ref_translator.get_published_min_refs.side_effect = res_method return ref_translator, depA, depB, baseC, full_graph
def test_diamond_single_solution(self): brl_a = BRLBlock('%s/%s/%s/master' % (self.user, self.user, 'blocka')) brl_b = BRLBlock('%s/%s/%s/master' % (self.user, self.user, 'blockb')) brl_c = BRLBlock('%s/%s/%s/master' % (self.user, self.user, 'blockc')) name_a = BlockCellName(self.user + "/blocka/a.h") publisher = TestPublisher(self.user, self.store) for _ in range(20): publisher.publish(brl_a, {'a.h': ('a', [])}) name_b = BlockCellName(self.user + "/blockb/b.h") name_c = BlockCellName(self.user + "/blockc/c.h") for i in range(0, 20): if i % 2 == 0: publisher.publish(brl_b, {'b.h': ('b', [name_a])}, dep_versions=BlockVersion(brl_a, i)) if (i % 2 == 1 or i == 10): publisher.publish(brl_c, {'c.h': ('c', [name_a])}, dep_versions=BlockVersion(brl_a, i)) request = self.build_unresolved_request([name_b, name_c]) result = self.service.find(request, BiiResponse()) self.check_result(result, resolved=[(brl_b, 5, {name_b}), (brl_c, 5, {name_c})])
def test_empty(self): '''when one is empty, always compatible''' c1 = CompatibilityClosure() c2 = CompatibilityClosure() self.assertEqual(0, c1.conflicts(c2)) self.assertEqual(0, c2.conflicts(c1)) brl0 = BRLBlock('user/user/block/master') brl1 = BRLBlock('user/user/block2/master') v0 = BlockVersion(brl0, 0) v2 = BlockVersion(brl1, 0) cell_id1 = ID((0, 0, 0)) cell_id2 = ID((0, 0, 1)) content_id1 = ID((0, 0, 0)) content_id2 = ID((0, 0, 1)) c1.add_item((cell_id1, content_id1), cell_id1, v0, 'file1') self.assertEqual(0, c1.conflicts(c2)) self.assertEqual(0, c2.conflicts(c1)) c1.add_item((cell_id2, content_id2), cell_id2, v2, 'file2') self.assertEqual(0, c1.conflicts(c2)) self.assertEqual(0, c2.conflicts(c1))
def test_add_delete_cell(self): publish_request = PublishRequest(BlockVersion(self.brl, -1)) publish_request.tag = STABLE publish_request.cells.append(SimpleCell('user/block/r1.h')) publish_request.contents['r1.h'] = Content(id_=None, load=None) self.block.add_publication(publish_request) self.assertEqual({'r1.h': ID(self.block_id + 0)}, self.block.cells.get_all_ids(0)) self.assertEqual({'r1.h': ID(self.block_id + 0)}, self.block.contents.get_all_ids(0)) publish_request = PublishRequest(BlockVersion(self.brl, 0)) publish_request.tag = STABLE publish_request.deleted.append('r1.h') self.block.add_publication(publish_request) self.assertEqual({'r1.h': self.block_id + 0}, self.block.cells.get_all_ids(0)) self.assertEqual({'r1.h': self.block_id + 0}, self.block.contents.get_all_ids(0)) self.assertEqual({}, self.block.cells.get_all_ids(1)) self.assertEqual({}, self.block.contents.get_all_ids(1)) self.assertEqual({}, self.block.last_version_cells())
def test_block_version_table(self): mv = BlockVersionTable() mv.add_version(BlockVersion('user/user/block/master', 1)) mv.add_version(BlockVersion('user/user/block/master', 1)) mv.add_version(BlockVersion('user/user/block/master', 1)) s = mv.serialize() mv2 = BlockVersionTable.deserialize(s) self.assertEqual(mv, mv2)
def test_serialize(self): bv = BlockVersion("user/user/math/master", 3, '2.7.1') s = bv.serialize() d = BlockVersion.deserialize(s) self.assertEquals(bv, d) bv = BlockVersion("user/user/math/master", 3) s = bv.serialize() d = BlockVersion.deserialize(s) self.assertEquals(bv, d)
def test_equals(self): brl = BRLBlock("user/user2/module/branch") v1 = BlockVersion(brl, 1) v2 = BlockVersion(brl, 2) self.assertNotEqual(v1, v2) self.assertEqual(brl, v1.block) self.assertEqual(1, v1.time) v3 = BlockVersion(brl, 2) self.assertEqual(v2, v3) v4 = BlockVersion(brl, 2, '1.2.3') self.assertEqual(v3, v4)
def test_references(self): r = References() bv3 = BlockVersion(BRLBlock('user/user/block/master'), 3) bv4 = BlockVersion(BRLBlock('user/user/block/master'), 4) cn0 = CellName('foo.h') cn1 = CellName('foo1.h') r[bv3].add(cn0) r[bv3].add(cn1) r[bv4].add(cn0) l = r.explode() self.assertEqual({(bv3, cn0), (bv3, cn1), (bv4, cn0)}, set(l))
def test_hasheable(self): brl = BRLBlock("user/user2/module/branch") v1 = BlockVersion(brl, 1) v2 = BlockVersion(brl, 2) v3 = BlockVersion(brl, 2) self.assertNotEquals(hash(v1), hash(v2)) self.assertEquals(hash(v3), hash(v2)) s = set() s.add(v1) s.add(v2) s.add(v3) self.assertEqual(2, len(s))
def test_cell_modify(self): '''check between time 1 and 2, a BiiType change''' version1 = BlockVersion(self.block, 1) version2 = BlockVersion(self.block, 2) changes = compare_remote_versions(self.service, version1, version2) self.assertEqual(0, len(changes.deleted)) self.assertEqual(0, len(changes.created)) self.assertEqual(0, len(changes.renames)) self.assertEqual(1, len(changes.modified)) self.assertEqual(UNKNOWN, changes.modified['r1.h'].old.cell.type) self.assertEqual(CPP, changes.modified['r1.h'].new.cell.type)
def test_content_modify(self): '''check between time 0 and 1, just a content edit''' version0 = BlockVersion(self.block, 0) version1 = BlockVersion(self.block, 1) changes = compare_remote_versions(self.service, version0, version1) self.assertEqual(0, len(changes.deleted)) self.assertEqual(0, len(changes.created)) self.assertEqual(0, len(changes.renames)) self.assertEqual(1, len(changes.modified)) diff = compute_diff(changes, resource_diff_function) self.assertEqual((None, '--- base\n\n+++ other\n\n@@ -1 +1 @@\n\n' '-hello\n+hello2'), diff.modified['r1.h'])
def test_basic(self): brl1 = BRLBlock("user/user2/block/branch") v1 = BlockVersion(brl1, 1) brl2 = BRLBlock("user2/user3/block2/branch3") v2 = BlockVersion(brl2, 2) table = BlockVersionTable() table.add_version(v1) table.add_version(v2) self.assertEqual(v1, table['user2/block']) self.assertEqual(v2, table['user3/block2']) self.assertEqual(2, len(table))
def simple_collisions_test(self): g1 = BlockVersionGraph() g2 = BlockVersionGraph() brl0 = BRLBlock('user/user/block/master') v0 = BlockVersion(brl0, 0) v1 = BlockVersion(brl0, 1) g1.add_node(v0) g2.add_node(v1) expected = BlockVersionGraph() expected.add_nodes([v0, v1]) self.assertEqual(expected, g1.collision(g2)) self.assertEqual(expected, g2.collision(g1))
def test_delete(self): '''4 => 5 r2.h is deleted''' version4 = BlockVersion(self.block, 4) version5 = BlockVersion(self.block, 5) changes = compare_remote_versions(self.service, version4, version5) self.assertEqual(1, len(changes.deleted)) self.assertEqual(0, len(changes.created)) self.assertEqual(0, len(changes.renames)) self.assertEqual(0, len(changes.modified)) diff = compute_diff(changes, resource_diff_function) self.assertEqual('--- base\n\n+++ other\n\n@@ -1 +0,0 @@\n\n-bye', diff.deleted['r2.h'].content) self.assertIsNotNone(diff.deleted['r2.h'].cell)
def test_resource_created(self): ''' 3 => 4 cell creation''' version3 = BlockVersion(self.block, 3) version4 = BlockVersion(self.block, 4) changes = compare_remote_versions(self.service, version3, version4) self.assertEqual(0, len(changes.deleted)) self.assertEqual(1, len(changes.created)) self.assertEqual(0, len(changes.renames)) self.assertEqual(0, len(changes.modified)) diff = compute_diff(changes, resource_diff_function) self.assertEqual('--- base\n\n+++ other\n\n@@ -0,0 +1 @@\n\n+bye', diff.created['r2.h'].content) #TODO: Implement and check diff of cell self.assertIsNotNone(diff.created['r2.h'].cell)
def disjoints_graphs_no_collisions_test(self): g1 = BlockVersionGraph() g2 = BlockVersionGraph() self.assertEqual(BlockVersionGraph(), g1.collision(g2)) self.assertEqual(BlockVersionGraph(), g2.collision(g1)) brl0 = BRLBlock('user/user/block/master') brl1 = BRLBlock('user/user/block2/master') v0 = BlockVersion(brl0, 0) v1 = BlockVersion(brl1, 1) g1.add_node(v0) g2.add_node(v1) self.assertEqual(BlockVersionGraph(), g1.collision(g2)) self.assertEqual(BlockVersionGraph(), g2.collision(g1))
def test_add_item(self): c1 = Closure() r1 = Cell('user/block/name1') version = BlockVersion(BRLBlock('owner/user/block/branch'), 13) biiout = OutputStream() resource = Resource(r1, None) c1.add_item(resource, version, biiout) r2 = Cell('user/block/name1') r2.hasMain = True resource2 = Resource(r2, None) version2 = BlockVersion(BRLBlock('owner/user/block/branch'), 14) c1.add_item(resource2, version2, biiout) self.assertEqual(ClosureItem(resource, version), c1['user/block/name1']) self.assertIn('Incompatible dependency', str(biiout))
def test_rename(self): version5 = BlockVersion(self.block, 5) version6 = BlockVersion(self.block, 6) changes = compare_remote_versions(self.service, version5, version6) self.assertEqual(1, len(changes.deleted)) self.assertEqual(1, len(changes.created)) self.assertEqual(1, len(changes.renames)) self.assertEqual(0, len(changes.modified)) self.assertEqual('r3.h', changes.renames['r1.h']) diff = compute_diff(changes, resource_diff_function) self.assertEqual(0, len(diff.deleted)) self.assertEqual(0, len(diff.created)) self.assertEqual('', diff.modified['r1.h'].content) self.assertIsNotNone(diff.modified['r1.h'].cell) self.assertEqual('r3.h', diff.renames['r1.h'])
def test_cell_content_modify(self): '''between time 0 and 2 there is content and biitype change''' version0 = BlockVersion(self.block, 0) version2 = BlockVersion(self.block, 2) changes = compare_remote_versions(self.service, version0, version2) self.assertEqual(0, len(changes.deleted)) self.assertEqual(0, len(changes.created)) self.assertEqual(0, len(changes.renames)) self.assertEqual(1, len(changes.modified)) self.assertEqual(UNKNOWN, changes.modified['r1.h'].old.cell.type) self.assertEqual(CPP, changes.modified['r1.h'].new.cell.type) diff = compute_diff(changes, resource_diff_function) self.assertEqual( '--- base\n\n+++ other\n\n@@ -1 +1 @@\n\n' '-hello\n+hello2', diff.modified['r1.h'].content)
def test_find_two_files_at_a_time(self): """Starts with one include, finds it, then two more includes, finish when all are found. Found items are taken into account in FindRequest.existing """ NUM_FILES = 10 brl_a = BRLBlock('%s/%s/%s/master' % (self.user, self.user, 'blocka')) names_a = [ BlockCellName(self.user + "/blocka/a%d.h" % i) for i in range(NUM_FILES) ] resources_info = {"a%d.h" % i: ("a", []) for i in range(NUM_FILES)} publisher = TestPublisher(self.user, self.store) publisher.publish(brl_a, resources_info) # Use the same request object, to accumulate existing (already found) files request = FinderRequest() request.policy = Policy.default() version = BlockVersion(brl_a, 0) # The version is always the same for i in range(0, NUM_FILES, 2): declaration1 = CPPDeclaration(names_a[i]) declaration2 = CPPDeclaration(names_a[i + 1]) request.unresolved = {declaration1, declaration2} result = self.service.find(request, BiiResponse()) self.check_result(result, resolved=[(brl_a, 0, {names_a[i], names_a[i + 1]})]) # The found one is added to the existing, for next iteration request.existing[version][declaration1] = {names_a[i]} request.existing[version][declaration2] = {names_a[i + 1]} self.assertEqual(len(request.existing[version]), i + 2)
def test_basic(self): store = TestingMemServerStore() brl_user = '******' store.create_user(User(brl_user)) brl_block = BRLBlock('user/user/block/master') publisher = TestPublisher(brl_user, store) publisher.publish( brl_block, { 'r1.h': ('r1', ['user/block/r2.h']), 'r2.h': ('r2', []), 'r3.h': ('r3', []) }) store = MemServerStore(store) translator = ReferenceTranslatorService(store, brl_user) ver = BlockVersion(brl_block, 0) missing = References() missing[ver].add('r1.h') closure = CompatibilityClosure(missing) full_graph = BlockVersionGraph() full_graph.add_nodes([ver]) build_compatibility_closure(translator, closure, {ver}, full_graph) self.assertEqual(References(), closure.broken) expected = set() expected.add('user/block/r1.h') expected.add('user/block/r2.h') self.assertEqual(expected, closure.block_cell_names)
def dep_overwriten_in_blocks_test(self): """ Blocks: C, B (None version) Deps: A C -> A -> B """ references = References() references[va].add('a.h') vbn = BlockVersion(vb.block, None) b = Resource(SimpleCell('user/blockb/b.h')) a = Resource(SimpleCell('user/blocka/a.h')) a2 = Resource(SimpleCell('user/blocka/a2.h')) a.cell.dependencies.explicit.add(a2.name) a2.cell.dependencies.explicit.add(b.name) tables = {va: [vb], vb: []} api = FakeApi(zip([va, va, vb], [a, a2, b]), tables) base_table = BlockVersionTable([vc, vbn]) biiout = OutputStream() graph, closure, _ = build_closure(api, references, base_table, biiout=biiout) expected_graph = BlockVersionGraph() expected_graph.add_nodes([va]) expected_graph.add_edge(va, vbn) self.assertEqual(expected_graph, graph) expected_closure = Closure({ a.name: ClosureItem(a, va), a2.name: ClosureItem(a2, va) }) self.assertEqual(expected_closure, closure) self.assertEqual("", str(biiout))
def _filter_by_policy(self, block_candidates, policy, biiresponse, original_date=None, request=None): '''computes list of (block_delta, block_version) for each block candidate''' delta_versions = [] for block_candidate in block_candidates: self.security.check_read_block(block_candidate) biiresponse.info("Block candidate: %s" % str(block_candidate)) block = self._store.read_block(block_candidate) # from last to 0, backwards for num_version in range(len(block.deltas) - 1, -1, -1): tag = block.deltas[num_version].tag date = block.deltas[num_version].date if request: if not request.downgrade and date <= original_date: continue version = BlockVersion(block.ID, num_version) ev = policy.evaluate(version, tag) if ev: heappush(delta_versions, ((-date, -num_version), version)) biiresponse.info("\tVersion %s (%s) valid" % (version, tag)) else: biiresponse.info("\tVersion %s (%s) discarded" % (version, tag)) return delta_versions
def setUp(self): self.folder = self.new_tmp_folder() brl_block = BRLBlock('dummy/dummy/block/master') self.block_version = BlockVersion(brl_block, 0) alf = Resource(SimpleCell("dummy/block/alf.c"), Content(ID((0, 1, 2)), Blob("Hello Alf"))) alf.cell.ID = ID((0, 1, 2)) willy = Resource(SimpleCell("dummy/block/willy.c"), Content(ID((0, 1, 3)), Blob("Hello Willy"))) willy.cell.ID = ID((0, 1, 45)) self.referenced_resources = ReferencedResources() self.referenced_resources[self.block_version].update({ CellName("alf.c"): alf, CellName("willy.c"): willy }) self.cells_snapshot = [CellName("alf.c"), CellName("willy.c")] self.dep_table = BlockVersionTable() self.restapi = Mock(BiiAPI) self.restapi.get_published_resources.return_value = self.referenced_resources self.restapi.get_cells_snapshot.return_value = self.cells_snapshot self.restapi.get_dep_table.return_value = self.dep_table self.restapi.get_version_delta_info.return_value = BlockDelta( '', DEV, None) self.localdb = LocalDB(os.path.join(self.folder, 'bii.db')) self.proxy = BiiAPIProxy(self.localdb, self.restapi, Mock())