def test_success_rollback_basic(self, mock_labbook_lfs_disabled): """ Basic test of rollback feature - making a branch from """ test_user_lb = mock_labbook_lfs_disabled[2] # Create a directory and capture that Git revision (to be used as basis for rollback). FileOperations.makedir(test_user_lb, relative_path='code/folder1', create_activity_record=True) commit = test_user_lb.git.commit_hash # Make follow-up changes to be reverted (sort of). FileOperations.makedir(test_user_lb, relative_path='code/folder2', create_activity_record=True) FileOperations.makedir(test_user_lb, relative_path='code/folder3', create_activity_record=True) # Make rollback branch from Git revision captured above. bm = BranchManager(test_user_lb, username=TEST_USER) new_b = bm.create_branch('rollback-from-folder-1', revision=commit) FileOperations.makedir(test_user_lb, relative_path='input/branch-folder', create_activity_record=True) # Check state of repo is as exptected assert os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder1')) assert not os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder2')) assert not os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder3')) # Now, make chagnes to rollback branch FileOperations.makedir(test_user_lb, relative_path='input/branch-1', create_activity_record=True) FileOperations.makedir(test_user_lb, relative_path='input/branch-2', create_activity_record=True) FileOperations.makedir(test_user_lb, relative_path='input/branch-3', create_activity_record=True) # Now, try pulling upstream changes back into the rollback branch, then demonstrate state # is as expected. bm.merge_from(bm.workspace_branch) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder2')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder3')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'input/branch-1')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'input/branch-2')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'input/branch-3')) assert test_user_lb.is_repo_clean
def test_success_merge_from(self, mock_labbook_lfs_disabled): """ Test merging with nonconflicting changes. """ lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) t = 'my-new-example-feature' feature_branch_name = bm.create_branch(title=t) assert bm.active_branch == feature_branch_name bm.workon_branch(bm.workspace_branch) FileOperations.makedir(lb, 'code/sillyfolder', create_activity_record=True) FileOperations.makedir(lb, 'input/newfolder', create_activity_record=True) bm.workon_branch(feature_branch_name) FileOperations.makedir(lb, 'output/otherdir', create_activity_record=True) bm.merge_from(bm.workspace_branch) # Assert repo state is as we expect assert os.path.isdir(os.path.join(lb.root_dir, 'code/sillyfolder')) assert os.path.isdir(os.path.join(lb.root_dir, 'input/newfolder')) assert os.path.isdir(os.path.join(lb.root_dir, 'output/otherdir')) assert lb.is_repo_clean # Return to original branch and check proper state bm.workon_branch(bm.workspace_branch) assert os.path.isdir(os.path.join(lb.root_dir, 'code/sillyfolder')) assert os.path.isdir(os.path.join(lb.root_dir, 'input/newfolder')) assert not os.path.isdir(os.path.join(lb.root_dir, 'output/otherdir')) assert lb.is_repo_clean
def mutate_and_get_payload(cls, root, info, owner, labbook_name, other_branch_name, override_method="abort", client_mutation_id=None): username = get_logged_in_username() lb = InventoryManager().load_labbook(username, owner, labbook_name, author=get_logged_in_author()) with lb.lock(): override = MergeOverride(override_method) bm = BranchManager(lb, username=username) if override == MergeOverride.ABORT: bm.merge_from(other_branch=other_branch_name) elif override == MergeOverride.OURS: bm.merge_use_ours(other_branch=other_branch_name) elif override == MergeOverride.THEIRS: bm.merge_use_theirs(other_branch=other_branch_name) else: raise ValueError(f"Unknown override method {override}") return MergeFromBranch( Labbook(id="{}&{}".format(owner, labbook_name), name=labbook_name, owner=owner))
def test_merge_conflict_basic(self, mock_labbook_lfs_disabled): """ Test a basic merge-conflict scenario with a conflict on one file. First, assert that a MergeConflict is raised when the conflict is detected Second, test the force flag to overwrite the conflict using the incoming branch.""" lb = mock_labbook_lfs_disabled[2] # Insert a text file into the master branch of lb with open('/tmp/s1.txt', 'w') as s1: s1.write('original-file\ndata') FileOperations.insert_file(lb, section='code', src_file=s1.name) # Create a new branch from this point and make a change to s1.txt bm = BranchManager(lb, username=TEST_USER) feature_name = bm.create_branch("example-feature-branch") with open('/tmp/s1.txt', 'w') as s1: s1.write('new-changes-in\nfeature-branch') FileOperations.insert_file(lb, section='code', src_file=s1.name) # Switch back to the main branch and make a new, conflicting change. bm.workon_branch(bm.workspace_branch) assert lb.is_repo_clean assert not os.path.exists(os.path.join(lb.root_dir, 'output/sample')) with open('/tmp/s1.txt', 'w') as s1: s1.write('upstream-changes-from-workspace') FileOperations.insert_file(lb, section='code', src_file=s1.name, dst_path='') # Switch back to feature branch -- make sure that failed merges rollback to state before merge. bm.workon_branch(feature_name) cp = bm.repository.git.commit_hash try: bm.merge_from(bm.workspace_branch) assert False, "merge_from should have thrown conflict" except MergeConflict as m: # Assert that the conflicted file(s) are as expected assert m.file_conflicts == ['code/s1.txt'] assert lb.is_repo_clean # Now try to force merge, and changes are taken from the workspace-branch bm.merge_use_ours(bm.workspace_branch) assert open(os.path.join(lb.root_dir, 'code', 's1.txt')).read(1000) == \ 'new-changes-in\nfeature-branch' assert lb.is_repo_clean # Reset this branch call_subprocess(f'git reset --hard {cp}'.split(), cwd=bm.repository.root_dir) bm.merge_use_theirs(bm.workspace_branch) assert open(os.path.join(lb.root_dir, 'code', 's1.txt')).read(1000) == \ 'upstream-changes-from-workspace' assert lb.is_repo_clean
def mutate_and_get_payload(cls, root, info, owner, labbook_name, other_branch_name, override_method="abort", client_mutation_id=None): username = get_logged_in_username() lb = InventoryManager().load_labbook(username, owner, labbook_name, author=get_logged_in_author()) with lb.lock(): override = MergeOverride(override_method) bm = BranchManager(lb, username=username) if override == MergeOverride.ABORT: bm.merge_from(other_branch=other_branch_name) elif override == MergeOverride.OURS: bm.merge_use_ours(other_branch=other_branch_name) elif override == MergeOverride.THEIRS: bm.merge_use_theirs(other_branch=other_branch_name) else: raise ValueError(f"Unknown override method {override}") # Run update_linked_datasets() to initialize and cleanup dataset submodules. You don't need to schedule # auto-import jobs because the user will have switched to the branch to pull it before merging. InventoryManager().update_linked_datasets(lb, username) return MergeFromBranch(Labbook(id="{}&{}".format(owner, labbook_name), name=labbook_name, owner=owner))