def test_query_mergeable_branches_from_main(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) b2 = bm.create_branch(f"tester2") bm.workon_branch(bm.workspace_branch) assert bm.active_branch == bm.workspace_branch q = f""" {{ labbook(name: "{UT_LBNAME}", owner: "{UT_USERNAME}") {{ branches {{ branchName isMergeable }} }} }} """ r = client.execute(q) assert 'errors' not in r assert len(r['data']['labbook']['branches']) == 3 assert r['data']['labbook']['branches'][0]['branchName'] == 'master' assert r['data']['labbook']['branches'][0]['isMergeable'] == False assert r['data']['labbook']['branches'][1]['branchName'] == 'tester1' assert r['data']['labbook']['branches'][1]['isMergeable'] == True assert r['data']['labbook']['branches'][2]['branchName'] == 'tester2' assert r['data']['labbook']['branches'][2]['isMergeable'] == True
def test_sync___override_merge_conflict_ours(self, mock_labbook_lfs_disabled, mock_config_file): """ test sync, with override in case of merge conflict. """ username = '******' lb = mock_labbook_lfs_disabled[2] wf = LabbookWorkflow(lb) wf.publish(username=username) bm = BranchManager(lb, username='******') bm.create_branch('test-conflict-branch') fpath = os.path.join(lb.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('filedata') lb.sweep_uncommitted_changes() wf.sync('test') other_user = '******' wf_other = LabbookWorkflow.import_from_remote( wf.remote, username=other_user, config_file=mock_config_file[0]) bm_other = BranchManager(wf_other.labbook, username=other_user) bm_other.workon_branch('test-conflict-branch') with open(os.path.join(wf_other.labbook.root_dir, 'input', 'testfile'), 'w') as f: f.write('conflicting-change-other-user') wf_other.labbook.sweep_uncommitted_changes() wf_other.sync(username=username) fpath = os.path.join(wf.labbook.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('conflicting-change-original-user') wf.labbook.sweep_uncommitted_changes() n = wf.sync(username=username, override=MergeOverride.OURS) flines = open(os.path.join(wf.labbook.root_dir, 'input', 'testfile')).read() assert 'conflicting-change-original-user' == flines
def test_fail_create_rollback_to_invalid_revision( self, mock_labbook_lfs_disabled): """ Fail when provided with an invalid Git revision """ test_user_lb = mock_labbook_lfs_disabled[2] bm = BranchManager(test_user_lb, username=TEST_USER) with pytest.raises(InvalidBranchName): bm.create_branch('should-fail', revision='invalidrevision')
def test_query_mergeable_branches_from_feature_branch( self, mock_create_labbooks): # Per current branch model, can only merge in workspace branch lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) b2 = bm.create_branch(f"tester2") q = f""" {{ labbook(name: "{UT_LBNAME}", owner: "{UT_USERNAME}") {{ workspaceBranchName branches {{ branchName isMergeable }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['labbook'][ 'workspaceBranchName'] == bm.workspace_branch branches = r['data']['labbook']['branches'] assert branches[0]['branchName'] == 'master' assert branches[0]['isMergeable'] is True assert branches[1]['branchName'] == 'tester1' assert branches[1]['isMergeable'] is True assert branches[2]['branchName'] == 'tester2' assert branches[2]['isMergeable'] is False
def remote_labbook_repo(): # TODO: Remove after integration tests with LFS support are available conf_file, working_dir = _create_temp_work_dir(lfs_enabled=False) im = InventoryManager(conf_file) lb = im.create_labbook('test', 'test', 'sample-repo-lb', description="my first labbook") bm = BranchManager(lb, username='******') bm.create_branch('testing-branch') #with tempfile.TemporaryDirectory() as tmpdirname: with open(os.path.join('/tmp', 'codefile.c'), 'wb') as codef: codef.write(b'// Cody McCodeface ...') FileOperations.insert_file(lb, "code", "/tmp/codefile.c") assert lb.is_repo_clean bm.workon_branch('master') # Location of the repo to push/pull from yield lb.root_dir shutil.rmtree(working_dir) try: os.remove('/tmp/codefile.c') except: pass
def test_sync___detect_merge_conflict(self, mock_labbook_lfs_disabled, mock_config_file): """ test import_from_remote method """ username = '******' lb = mock_labbook_lfs_disabled[2] wf = LabbookWorkflow(lb) wf.publish(username=username) bm = BranchManager(lb, username='******') bm.create_branch('test-conflict-branch') fpath = os.path.join(lb.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('filedata') lb.sweep_uncommitted_changes() wf.sync('test') other_user = '******' wf_other = LabbookWorkflow.import_from_remote( wf.remote, username=other_user, config_file=mock_config_file[0]) bm_other = BranchManager(wf_other.labbook, username=other_user) bm_other.workon_branch('test-conflict-branch') with open(os.path.join(wf_other.labbook.root_dir, 'input', 'testfile'), 'w') as f: f.write('conflicting-change-other-user') wf_other.labbook.sweep_uncommitted_changes() wf_other.sync(username=username) with open(fpath, 'w') as f: f.write('conflicting-change-original-user') wf.labbook.sweep_uncommitted_changes() h = wf.labbook.git.commit_hash with pytest.raises(MergeConflict): n = wf.sync(username=username) assert h == wf.labbook.git.commit_hash
def test_fail_create_branch_duplicate_name(self, mock_labbook_lfs_disabled): """ Ensure cannot create a new branch with name of existing branch """ t = "branch-to-be-made-twice" lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) bm.create_branch(title=t) with pytest.raises(InvalidBranchName): bm.create_branch(title=t)
def test_success_create_branch_simple(self, mock_labbook_lfs_disabled): """ Test basic creation of a new branch""" t = "my-first-feature-branch" lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) assert bm.active_branch == 'master' bm.create_branch(title=t) assert bm.active_branch == t assert lb.is_repo_clean is True
def migrate_labbook_branches(labbook: LabBook) -> None: bm = BranchManager(labbook) if 'gm.workspace' not in bm.active_branch: raise ValueError('Can only migrate branches if active branch contains' '"gm.workspace"') master_branch = 'master' if master_branch in bm.branches_local: bm.remove_branch(master_branch) bm.create_branch(master_branch)
def test_sync___push_up_new_branch(self, mock_labbook_lfs_disabled, mock_config_file): """ test import_from_remote method """ username = '******' lb = mock_labbook_lfs_disabled[2] wf = LabbookWorkflow(lb) wf.publish(username=username) bm = BranchManager(lb, username='******') bm.create_branch('new-branch-to-push') assert 'new-branch-to-push' not in bm.branches_remote wf.sync('test') assert 'new-branch-to-push' in bm.branches_remote
def test_count_commits_behind_for_local_branch(self, mock_config_file, remote_labbook_repo, mock_labbook_lfs_disabled): # When we're using a local branch, by definition it is never behind. lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username='******') lb.add_remote("origin", remote_labbook_repo) bm.create_branch("super-local-branch") bm.fetch() behind = bm.get_commits_behind() ahead = bm.get_commits_ahead() # Should be up-to-date. assert ahead == 0 assert behind == 0
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, branch_name, revision=None, description=None, 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(): bm = BranchManager(lb, username=username) full_branch_title = bm.create_branch(title=branch_name, revision=revision) logger.info( f"In {str(lb)} created new experimental feature branch: " f"{full_branch_title}") if description: cls._update_branch_description(lb, description) return CreateExperimentalBranch( Labbook(id="{}&{}".format(owner, labbook_name), name=labbook_name, owner=owner))
def test_delete_feature_branch_success(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) q = f""" mutation makeFeatureBranch {{ deleteExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "{b1}", deleteLocal: true }}) {{ labbook {{ branches {{ branchName }} }} }} }} """ r = client.execute(q) pprint.pprint(r) # Cannot delete branch when it's the currently active branch assert 'errors' not in r assert bm.active_branch == bm.workspace_branch assert lb.is_repo_clean assert b1 not in bm.branches_local
def test_create_feature_branch_success(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) q = f""" mutation makeFeatureBranch {{ createExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "valid-branch-name-working1" }}) {{ labbook{{ name activeBranchName branches {{ branchName }} }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['createExperimentalBranch']['labbook']['activeBranchName'] \ == 'valid-branch-name-working1' assert set([n['branchName'] for n in r['data']['createExperimentalBranch']['labbook']['branches']]) \ == set(['tester1', 'master', 'valid-branch-name-working1']) assert lb.active_branch == 'valid-branch-name-working1' assert lb.is_repo_clean
def test_reflect_deleted_files_on_merge_in(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] with open('/tmp/s1.txt', 'w') as s1: s1.write('original-file\ndata') FileOperations.insert_file(lb, section='code', src_file=s1.name) bm = BranchManager(lb, username=UT_USERNAME) nb = bm.create_branch(f'new-branch') assert os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt')) FileOperations.delete_files(lb, 'code', ['s1.txt']) assert lb.is_repo_clean assert not os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt')) bm.workon_branch(bm.workspace_branch) assert os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt')) merge_q = f""" mutation x {{ mergeFromBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", otherBranchName: "{nb}" }}) {{ labbook{{ name description activeBranchName }} }} }} """ r = client.execute(merge_q) assert 'errors' not in r assert r['data']['mergeFromBranch']['labbook']['activeBranchName'] == 'master' assert not os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt'))
def test_conflicted_merge_from_no_force_fail(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] with open('/tmp/s1.txt', 'w') as s1: s1.write('original-file\ndata') FileOperations.insert_file(lb, section='code', src_file=s1.name) bm = BranchManager(lb, username=UT_USERNAME) nb = bm.create_branch(f'new-branch') with open('/tmp/s1.txt', 'w') as s1: s1.write('branch-conflict-data') FileOperations.insert_file(lb, section='code', src_file=s1.name) bm.workon_branch(bm.workspace_branch) with open('/tmp/s1.txt', 'w') as s1: s1.write('mainline-conflict-data') FileOperations.insert_file(lb, section='code', src_file=s1.name) merge_q = f""" mutation x {{ mergeFromBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", otherBranchName: "{nb}" }}) {{ labbook{{ name description activeBranchName }} }} }} """ r = client.execute(merge_q) assert 'errors' in r assert 'Merge conflict' in r['errors'][0]['message']
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_workon_feature_branch_success(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) assert bm.active_branch == 'master' q = f""" mutation makeFeatureBranch {{ workonExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "{b1}" }}) {{ labbook{{ name description branches {{ branchName }} activeBranchName }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['workonExperimentalBranch']['labbook']['activeBranchName'] \ == 'tester1' ab = r['data']['workonExperimentalBranch']['labbook']['branches'] assert set([n['branchName'] for n in ab]) \ == set(['master', 'tester1']) assert bm.active_branch == 'tester1' assert lb.is_repo_clean
def test_sync___push_up_then_sync(self, mock_labbook_lfs_disabled, mock_config_file): """ test import_from_remote method """ username = '******' lb = mock_labbook_lfs_disabled[2] wf = LabbookWorkflow(lb) wf.publish(username=username) bm = BranchManager(lb, username='******') bm.create_branch('new-branch-to-push') wf.sync('test') # Make some change locally and commit, then sync. fpath = os.path.join(lb.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('filedata') lb.sweep_uncommitted_changes() wf.sync(username=username)
def test_objects_to_push_ignore_other_branch(self, mock_dataset_with_manifest): ds, manifest, working_dir = mock_dataset_with_manifest iom = IOManager(ds, manifest) revision = manifest.dataset_revision os.makedirs( os.path.join(manifest.cache_mgr.cache_root, revision, "other_dir")) helper_append_file(manifest.cache_mgr.cache_root, revision, "test1.txt", "test content 1") helper_append_file(manifest.cache_mgr.cache_root, revision, "test2.txt", "fdsfgfd") manifest.sweep_all_changes() obj_to_push = iom.objects_to_push() assert len(obj_to_push) == 2 assert obj_to_push[0].dataset_path == "test1.txt" assert obj_to_push[1].dataset_path == "test2.txt" # Create new branch and add a file there bm = BranchManager(ds, username=USERNAME) starting_branch = bm.active_branch bm.create_branch(title="test-branch") assert bm.active_branch == "test-branch" assert ds.is_repo_clean is True helper_append_file(manifest.cache_mgr.cache_root, iom.manifest.dataset_revision, "test3.txt", "fdsfgfd") manifest.sweep_all_changes() obj_to_push = iom.objects_to_push() assert len(obj_to_push) == 3 assert obj_to_push[0].dataset_path == "test1.txt" assert obj_to_push[1].dataset_path == "test2.txt" assert obj_to_push[2].dataset_path == "test3.txt" # Go back to original branch, you shouldn't have to push file on other branch bm.workon_branch(starting_branch) obj_to_push = iom.objects_to_push() assert len(obj_to_push) == 2 assert obj_to_push[0].dataset_path == "test1.txt" assert obj_to_push[1].dataset_path == "test2.txt"
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 test_success_remove_branch(self, mock_labbook_lfs_disabled): """ Test that branches can be removed locally """ lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) t = 'branch-to-make-and-then-delete' branch_name_to_delete = bm.create_branch(title=t) assert branch_name_to_delete in bm.branches_local bm.workon_branch(bm.workspace_branch) bm.remove_branch(branch_name_to_delete) assert branch_name_to_delete not in bm.branches_local
def test_merge_into_feature_from_workspace_simple_success( self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) og_hash = lb.git.commit_hash b1 = bm.create_branch(f"test-branch") bm.workon_branch(bm.workspace_branch) assert lb.active_branch == bm.workspace_branch og2_hash = lb.git.commit_hash assert lb.git.commit_hash == og_hash FileOperations.makedir(lb, 'code/main-branch-dir1', create_activity_record=True) FileOperations.makedir(lb, 'code/main-branch-dir2', create_activity_record=True) next_main_hash = lb.git.commit_hash assert og_hash != next_main_hash bm.workon_branch(b1) assert not os.path.exists( os.path.join(lb.root_dir, 'code/main-branch-dir1')) merge_q = f""" mutation x {{ mergeFromBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", otherBranchName: "{bm.workspace_branch}" }}) {{ labbook{{ name description activeBranchName }} }} }} """ r = client.execute(merge_q) assert 'errors' not in r assert r['data']['mergeFromBranch']['labbook'][ 'activeBranchName'] == 'test-branch' assert r['data']['mergeFromBranch']['labbook'][ 'name'] == 'unittest-workflow-branch-1' assert lb.active_branch == b1 assert os.path.exists( os.path.join(lb.root_dir, 'code/main-branch-dir1')) assert lb.is_repo_clean
def test_publish__simple(self, mock_labbook_lfs_disabled): """Test a simple publish and ensuring master is active branch. """ username = '******' lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username) bm.create_branch('test-local-only') assert bm.branches_remote == [] assert bm.branches_local == ['master', 'test-local-only'] wf = LabbookWorkflow(lb) # Test you can only publish on master. with pytest.raises(GitWorkflowException): wf.publish(username=username) assert wf.remote is None # Once we return to master branch, then we can publish. bm.workon_branch(bm.workspace_branch) wf.publish(username=username) assert os.path.exists(wf.remote) # Assert that publish only pushes up the master branch. assert bm.branches_local == ['master', 'test-local-only'] assert bm.branches_remote == ['master']
def test_success_create_branch_then_return_to_master(self, mock_labbook_lfs_disabled): """ Test process of creating a new branch, then returning to original and then being in a clean state. """ t = 'my-new-example-feature' lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) assert bm.active_branch == 'master' branch_name = bm.create_branch(title=t) assert bm.active_branch == branch_name assert lb.is_repo_clean bm.workon_branch(bm.workspace_branch) assert bm.active_branch == 'master' assert lb.active_branch == 'master' assert lb.is_repo_clean
def test_create_feature_branch_from_feature_branch_fail(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") q = f""" mutation makeFeatureBranch {{ createExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "valid-branch-name" }}) {{ newBranchName }} }} """ r = client.execute(q) pprint.pprint(r) assert 'errors' in r assert bm.active_branch == b1 assert lb.is_repo_clean
def test_create_feature_branch_success_update_description( self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) q = f""" mutation makeFeatureBranch {{ createExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "valid-branch-name-working1" description: "Updated description" }}) {{ labbook{{ name description branches {{ branchName }} activeBranchName }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['createExperimentalBranch']['labbook']['activeBranchName'] \ == 'valid-branch-name-working1' assert r['data']['createExperimentalBranch']['labbook']['description'] \ == "Updated description" assert bm.active_branch == 'valid-branch-name-working1' assert lb.is_repo_clean # Make sure activity record was created when description was changed log_data = lb.git.log() assert "_GTM_ACTIVITY_START_**\nmsg:Updated description of Project" in log_data[ 0]['message']
def test_workon_feature_branch_bad_name_fail(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) q = f""" mutation makeFeatureBranch {{ workonExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "{b1.replace('gm', '')}" }}) {{ currentBranchName }} }} """ r = client.execute(q) pprint.pprint(r) # Cannot delete branch when it's the currently active branch assert 'errors' in r assert bm.active_branch == bm.workspace_branch assert lb.is_repo_clean
def test_link_unlink_dataset_across_branches(self, mock_labbook): """Test to verify linked Dataset initialization works across branching in Projects - Create a project - Create a dataset - Link dataset on master - Switch to another branch - Unlink dataset: dataset is gone - Switch to master: dataset is available - Switch to other branch: dataset is gone - Switch to master: dataset is available """ inv_manager = InventoryManager(mock_labbook[0]) lb = mock_labbook[2] ds = inv_manager.create_dataset("test", "test", "dataset100", "gigantum_object_v1", description="my dataset") # Fake publish to a local bare repo _MOCK_create_remote_repo2(ds, 'test', None, None) assert os.path.exists(os.path.join(lb.root_dir, '.gitmodules')) is False # link dataset and make sure it's there inv_manager.link_dataset_to_labbook(ds.remote, 'test', 'dataset100', lb) assert os.path.exists(os.path.join(lb.root_dir, '.gitmodules')) is True dataset_submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets', 'test', 'dataset100') assert os.path.exists(dataset_submodule_dir) is True assert os.path.exists(os.path.join(dataset_submodule_dir, '.gigantum')) is True # Create a branch bm = BranchManager(lb, username="******") assert bm.active_branch == 'master' branch_name = bm.create_branch(title="test-branch") assert bm.active_branch == branch_name assert lb.is_repo_clean # Dataset still there assert os.path.exists(os.path.join(lb.root_dir, '.gitmodules')) is True dataset_submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets', 'test', 'dataset100') assert os.path.exists(dataset_submodule_dir) is True assert os.path.exists(os.path.join(dataset_submodule_dir, '.gigantum')) is True # Unlink dataset in branch inv_manager.unlink_dataset_from_labbook('test', 'dataset100', lb) # Dataset gone dataset_submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets', 'test', 'dataset100') assert os.path.exists(dataset_submodule_dir) is False assert os.path.exists(os.path.join(dataset_submodule_dir, '.gigantum')) is False with open(os.path.join(lb.root_dir, '.gitmodules'), 'rt') as mf: data = mf.read() assert len(data) == 0 # Switch back to master bm.workon_branch('master') assert bm.active_branch == 'master' assert lb.active_branch == 'master' assert lb.is_repo_clean # Dataset is back! assert os.path.exists(os.path.join(lb.root_dir, '.gitmodules')) is True dataset_submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets', 'test', 'dataset100') assert os.path.exists(dataset_submodule_dir) is True assert os.path.exists(os.path.join(dataset_submodule_dir, '.gigantum')) is True with open(os.path.join(lb.root_dir, '.gitmodules'), 'rt') as mf: data = mf.read() assert len(data) > 0 # Switch back to branch bm.workon_branch('test-branch') assert bm.active_branch == 'test-branch' assert lb.active_branch == 'test-branch' assert lb.is_repo_clean dataset_submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets', 'test', 'dataset100') assert os.path.exists(dataset_submodule_dir) is False assert os.path.exists(os.path.join(dataset_submodule_dir, '.gigantum')) is False with open(os.path.join(lb.root_dir, '.gitmodules'), 'rt') as mf: data = mf.read() assert len(data) == 0 # Switch back to master bm.workon_branch('master') assert bm.active_branch == 'master' assert lb.active_branch == 'master' assert lb.is_repo_clean # Dataset is back! assert os.path.exists(os.path.join(lb.root_dir, '.gitmodules')) is True dataset_submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets', 'test', 'dataset100') assert os.path.exists(dataset_submodule_dir) is True assert os.path.exists(os.path.join(dataset_submodule_dir, '.gigantum')) is True with open(os.path.join(lb.root_dir, '.gitmodules'), 'rt') as mf: data = mf.read() assert len(data) > 0