def test_remove_remote_branch(self, mock_labbook_lfs_disabled):
        lb = mock_labbook_lfs_disabled[2]

        with tempfile.TemporaryDirectory() as tempdir:
            call_subprocess('git init .'.split(), tempdir)
            call_subprocess('touch FILE_A'.split(), tempdir)
            call_subprocess('git add FILE_A'.split(), tempdir)
            call_subprocess('git commit -am "message"'.split(), tempdir)
            call_subprocess('git checkout -b remote-branch'.split(),
                            cwd=tempdir)
            call_subprocess('git checkout master'.split(), cwd=tempdir)
            lb.git.add_remote('origin', tempdir)
            bm = BranchManager(lb)
            bm.fetch()
            assert 'remote-branch' in bm.branches_remote

            # Get this remote branch locally, but go back to master
            bm.workon_branch('remote-branch')
            call_subprocess('git checkout master'.split(),
                            cwd=bm.repository.root_dir)
            bm.remove_remote_branch('remote-branch')

            bm.fetch()

            # Confirm branch exists locally, but is gone on remote.
            assert 'remote-branch' in bm.branches_local
            assert 'remote-branch' not in bm.branches_remote
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #4
0
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
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
    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']
Exemple #8
0
    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'))
Exemple #9
0
    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___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_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_assert_all_remote_branches_can_be_checked_out(
            self, mock_config_file, remote_labbook_repo,
            mock_labbook_lfs_disabled):
        # Make sure all local branches can be checked out
        lb = mock_labbook_lfs_disabled[2]
        bm = BranchManager(lb, username=TEST_USER)

        # There is a remote branch called "testing-branch"
        lb.add_remote("origin", remote_labbook_repo)
        for branch_name in bm.branches_remote:
            bm.workon_branch(branch_name)
    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
Exemple #14
0
    def test_count_commits_behind_remote_when_no_change(self, mock_config_file, remote_labbook_repo,
                                                        mock_labbook_lfs_disabled):
        # When the branch is up to date, ensure it doesn't report being behind.
        lb = mock_labbook_lfs_disabled[2]
        bm = BranchManager(lb, username='******')
        lb.add_remote("origin", remote_labbook_repo)
        bm.workon_branch('testing-branch')

        bm.fetch()
        behind = bm.get_commits_behind()
        ahead = bm.get_commits_ahead()
        assert ahead == 0
        assert behind == 0
    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
Exemple #16
0
    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
Exemple #17
0
    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
Exemple #18
0
    def test_get_commits_with_local_changes(self, mock_config_file, remote_labbook_repo,
                                            mock_labbook_lfs_disabled):
        # When the branch is up to date, ensure it doesn't report being behind.
        lb = mock_labbook_lfs_disabled[2]
        lb.add_remote("origin", remote_labbook_repo)
        bm = BranchManager(lb, username='******')
        bm.workon_branch("testing-branch")

        # Do some stuff to make commits locally
        FileOperations.makedir(lb, 'code/rand_dir', create_activity_record=True)
        FileOperations.delete_files(lb, 'code', ['rand_dir'])

        behind = bm.get_commits_behind()
        ahead = bm.get_commits_ahead()
        assert ahead == 4
        assert behind == 0
Exemple #19
0
    def checkout(self, username: str, branch_name: str) -> None:
        """Workflow method to checkout a branch in a Project, and if a new linked dataset has been introduced,
        automatically import it.

        Args:
            username: Current logged in username
            branch_name: name of the branch to checkout

        Returns:
            None
        """
        # Checkout the branch
        bm = BranchManager(self.labbook, username=username)
        bm.workon_branch(branch_name=branch_name)

        # Update linked datasets inside the Project, clean them out if needed, and schedule auto-imports
        gitworkflows_utils.process_linked_datasets(self.labbook, 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"
Exemple #21
0
 def mutate_and_get_payload(cls,
                            root,
                            info,
                            owner,
                            labbook_name,
                            branch_name,
                            client_mutation_id=None):
     username = get_logged_in_username()
     lb = InventoryManager().load_labbook(username,
                                          owner,
                                          labbook_name,
                                          author=get_logged_in_author())
     # TODO - fail fast if already locked.
     with lb.lock():
         bm = BranchManager(lb, username=username)
         bm.workon_branch(branch_name=branch_name)
     return WorkonBranch(
         Labbook(id="{}&{}".format(owner, labbook_name),
                 name=labbook_name,
                 owner=owner))
Exemple #22
0
    def test_get_commits_with_remote_changes(self, mock_config_file,
                                             remote_labbook_repo,
                                             mock_labbook_lfs_disabled):
        # When the branch is up to date, ensure it doesn't report being behind.
        lb = mock_labbook_lfs_disabled[2]
        lb.add_remote("origin", remote_labbook_repo)
        bm = BranchManager(lb, username='******')
        bm.workon_branch("testing-branch")

        from gtmcore.inventory.inventory import InventoryManager
        remote_lb = InventoryManager(mock_config_file[0]).load_labbook_from_directory(remote_labbook_repo)
        remote_bm = BranchManager(remote_lb, 'test')
        remote_bm.workon_branch("testing-branch")
        FileOperations.makedir(remote_lb, 'code/xyzdir', create_activity_record=True)


        bm.fetch()
        behind = bm.get_commits_behind()
        ahead = bm.get_commits_ahead()
        assert ahead == 0
        assert behind == 2
    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
Exemple #24
0
    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']
Exemple #25
0
    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_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_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
Exemple #28
0
    def test_commits_ahead_behind(self, fixture_working_dir_lfs_disabled):
        with responses.RequestsMock() as rsps:
            rsps.add(responses.GET,
                     'https://usersrv.gigantum.io/key',
                     json={'key': 'afaketoken'},
                     status=200)

            config_file, client = fixture_working_dir_lfs_disabled[0], \
                                     fixture_working_dir_lfs_disabled[2]

            im = InventoryManager(config_file)
            lb = im.create_labbook(UT_USERNAME,
                                   UT_USERNAME,
                                   UT_LBNAME,
                                   description="tester")
            bm = BranchManager(lb, username=UT_USERNAME)
            bm.create_branch('new-branch-1')
            bm.create_branch('new-branch-2')
            bm.workon_branch('master')

            q = f"""
            {{
                labbook(name: "{UT_LBNAME}", owner: "{UT_USERNAME}") {{
                    branches {{
                        branchName
                        isLocal
                        isRemote
                        isActive
                        commitsAhead
                        commitsBehind
                    }}
                }}
            }}
            """

            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][
                'isLocal'] is True, "Should be local"
            assert r['data']['labbook']['branches'][0][
                'isRemote'] is False, "not published yet"
            assert r['data']['labbook']['branches'][0]['isActive'] is True
            assert r['data']['labbook']['branches'][0]['commitsAhead'] == 0
            assert r['data']['labbook']['branches'][0]['commitsBehind'] == 0

            # Make a remote change!
            username = '******'
            wf = LabbookWorkflow(lb)
            wf.publish(username=username)

            other_user = '******'
            wf_other = LabbookWorkflow.import_from_remote(
                remote_url=wf.remote,
                username=other_user,
                config_file=lb.client_config.config_file)
            with open(os.path.join(wf_other.repository.root_dir, 'testfile'),
                      'w') as f:
                f.write('filedata')
            wf_other.repository.sweep_uncommitted_changes()

            wf_other.sync(username=other_user)

            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][
                'isLocal'] is True, "Should be local"
            assert r['data']['labbook']['branches'][0][
                'isRemote'] is True, "There should be a remote"
            assert r['data']['labbook']['branches'][0]['isActive'] is True
            assert r['data']['labbook']['branches'][0]['commitsAhead'] == 0
            assert r['data']['labbook']['branches'][0]['commitsBehind'] == 1

            # Make a local change!
            lb.write_readme("blah")

            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][
                'isLocal'] is True, "Should be local"
            assert r['data']['labbook']['branches'][0][
                'isRemote'] is True, "There should be a remote"
            assert r['data']['labbook']['branches'][0]['isActive'] is True
            assert r['data']['labbook']['branches'][0]['commitsAhead'] == 1
            assert r['data']['labbook']['branches'][0]['commitsBehind'] == 1

            # Sync
            wf.sync(username=username)
            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][
                'isLocal'] is True, "Should be local"
            assert r['data']['labbook']['branches'][0][
                'isRemote'] is True, "There should be a remote"
            assert r['data']['labbook']['branches'][0]['isActive'] is True
            assert r['data']['labbook']['branches'][0]['commitsAhead'] == 0
            assert r['data']['labbook']['branches'][0]['commitsBehind'] == 0