org.eclipse.orion.server.tests.servlets.git.GitBranchTest.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.orion.server.tests.servlets.git.GitBranchTest.java

Source

/*******************************************************************************
 * Copyright (c) 2011, 2012 IBM Corporation and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.orion.server.tests.servlets.git;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.net.HttpURLConnection;
import java.net.URI;

import org.eclipse.core.runtime.IPath;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.PullResult;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.git.GitConstants;
import org.eclipse.orion.server.tests.servlets.internal.DeleteMethodWebRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;

import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;

public class GitBranchTest extends GitTest {
    @Test
    public void testListBranches() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        String workspaceId = workspaceIdFromLocation(workspaceLocation);
        JSONObject project = createProjectOrLink(workspaceLocation, getMethodName(), null);
        IPath clonePath = getClonePath(workspaceId, project);
        JSONObject clone = clone(clonePath);
        String branchesLocation = clone.getString(GitConstants.KEY_BRANCH);

        branch(branchesLocation, "a");
        branch(branchesLocation, "z");

        JSONObject branches = listBranches(branchesLocation);
        JSONArray branchesArray = branches.getJSONArray(ProtocolConstants.KEY_CHILDREN);
        assertEquals(3, branchesArray.length());

        // validate branch metadata
        JSONObject branch = branchesArray.getJSONObject(1);
        assertEquals(Constants.MASTER, branch.getString(ProtocolConstants.KEY_NAME));
        assertBranchUri(branch.getString(ProtocolConstants.KEY_LOCATION));
        assertTrue(branch.optBoolean(GitConstants.KEY_BRANCH_CURRENT, false));
        branch = branchesArray.getJSONObject(0);
        assertEquals("z", branch.getString(ProtocolConstants.KEY_NAME));
        // assert properly sorted, new first
        long lastTime = Long.MAX_VALUE;
        for (int i = 0; i < branchesArray.length(); i++) {
            long t = branchesArray.getJSONObject(i).getLong(ProtocolConstants.KEY_LOCAL_TIMESTAMP);
            assertTrue(t <= lastTime);
            lastTime = t;
        }
    }

    @Test
    public void testAddRemoveBranch() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        String workspaceId = workspaceIdFromLocation(workspaceLocation);
        JSONObject project = createProjectOrLink(workspaceLocation, getMethodName(), null);
        IPath clonePath = getClonePath(workspaceId, project);
        JSONObject clone = clone(clonePath);
        String branchesLocation = clone.getString(GitConstants.KEY_BRANCH);

        String[] branchNames = { "dev", "change/1/1", "working@bug1" };
        for (String branchName : branchNames) {
            // create branch
            WebResponse response = branch(branchesLocation, branchName);
            String branchLocation = response.getHeaderField(ProtocolConstants.HEADER_LOCATION);

            // check details
            WebRequest request = getGetRequest(branchLocation);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            JSONObject branches = listBranches(branchesLocation);
            JSONArray branchesArray = branches.getJSONArray(ProtocolConstants.KEY_CHILDREN);
            assertEquals(2, branchesArray.length());
            JSONObject branch0 = branchesArray.getJSONObject(0);
            JSONObject branch1 = branchesArray.getJSONObject(1);
            if (branch0.optBoolean(GitConstants.KEY_BRANCH_CURRENT, false))
                assertFalse(branch1.optBoolean(GitConstants.KEY_BRANCH_CURRENT, false));
            else
                assertTrue(branch1.optBoolean(GitConstants.KEY_BRANCH_CURRENT, false));

            // remove branch
            request = getDeleteGitBranchRequest(branchLocation);
            response = webConversation.getResponse(request);
            assertTrue(HttpURLConnection.HTTP_OK == response.getResponseCode()
                    || HttpURLConnection.HTTP_ACCEPTED == response.getResponseCode());

            // list branches again, make sure it's gone
            request = getGetRequest(branchesLocation);
            response = webConversation.getResponse(request);
            ServerStatus status = waitForTask(response);
            assertTrue(status.toString(), status.isOK());
            branches = status.getJsonData();
            branchesArray = branches.getJSONArray(ProtocolConstants.KEY_CHILDREN);
            assertEquals(1, branchesArray.length());
            JSONObject branch = branchesArray.getJSONObject(0);
            assertTrue(branch.optBoolean(GitConstants.KEY_BRANCH_CURRENT, false));
        }
    }

    @Test
    public void testCreateTrackingBranch() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        IPath[] clonePaths = createTestProjects(workspaceLocation);

        for (IPath clonePath : clonePaths) {
            // clone a  repo
            JSONObject clone = clone(clonePath);
            String cloneLocation = clone.getString(ProtocolConstants.KEY_LOCATION);
            String cloneContentLocation = clone.getString(ProtocolConstants.KEY_CONTENT_LOCATION);
            String branchesLocation = clone.getString(GitConstants.KEY_BRANCH);

            // overwrite user settings, do not rebase when pulling, see bug 372489
            StoredConfig cfg = getRepositoryForContentLocation(cloneContentLocation).getConfig();
            cfg.setBoolean(ConfigConstants.CONFIG_BRANCH_SECTION, Constants.MASTER,
                    ConfigConstants.CONFIG_KEY_REBASE, false);
            cfg.save();

            // get project/folder metadata
            WebRequest request = getGetRequest(cloneContentLocation);
            WebResponse response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject project = new JSONObject(response.getText());

            JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
            String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);
            String gitRemoteUri = gitSection.optString(GitConstants.KEY_REMOTE);

            // create local branch tracking origin/master
            final String BRANCH_NAME = "a";
            final String REMOTE_BRANCH = Constants.DEFAULT_REMOTE_NAME + "/" + Constants.MASTER;

            branch(branchesLocation, BRANCH_NAME, REMOTE_BRANCH);

            // modify, add, commit
            JSONObject testTxt = getChild(project, "test.txt");
            modifyFile(testTxt, "some change");
            addFile(testTxt);
            request = GitCommitTest.getPostGitCommitRequest(gitHeadUri, "commit1", false);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // push
            ServerStatus pushStatus = push(gitRemoteUri, 1, 0, Constants.MASTER, Constants.HEAD, false);
            assertEquals(true, pushStatus.isOK());

            // TODO: replace with RESTful API for git pull when available
            // try to pull - up to date status is expected
            Git git = new Git(getRepositoryForContentLocation(cloneContentLocation));
            PullResult pullResults = git.pull().call();
            assertEquals(Constants.DEFAULT_REMOTE_NAME, pullResults.getFetchedFrom());
            assertEquals(MergeStatus.ALREADY_UP_TO_DATE, pullResults.getMergeResult().getMergeStatus());
            assertNull(pullResults.getRebaseResult());

            // checkout branch which was created a moment ago
            response = checkoutBranch(cloneLocation, BRANCH_NAME);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // TODO: replace with RESTful API for git pull when available
            // try to pull again - now fast forward update is expected
            pullResults = git.pull().call();
            assertEquals(Constants.DEFAULT_REMOTE_NAME, pullResults.getFetchedFrom());
            assertEquals(MergeStatus.FAST_FORWARD, pullResults.getMergeResult().getMergeStatus());
            assertNull(pullResults.getRebaseResult());
        }
    }

    @Test
    public void testCheckoutAmbiguousName() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        IPath[] clonePaths = createTestProjects(workspaceLocation);

        for (IPath clonePath : clonePaths) {
            // clone a  repo
            JSONObject clone = clone(clonePath);
            String cloneLocation = clone.getString(ProtocolConstants.KEY_LOCATION);
            String cloneContentLocation = clone.getString(ProtocolConstants.KEY_CONTENT_LOCATION);
            String branchesLocation = clone.getString(GitConstants.KEY_BRANCH);

            // get project/folder metadata
            WebRequest request = getGetRequest(cloneContentLocation);
            WebResponse response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject folder = new JSONObject(response.getText());

            JSONObject testTxt = getChild(folder, "test.txt");
            modifyFile(testTxt, "tagged");
            addFile(testTxt);
            commitFile(testTxt, "tagged", false);

            // tag HEAD with 'tag'
            JSONObject gitSection = folder.getJSONObject(GitConstants.KEY_GIT);
            String gitTagUri = gitSection.getString(GitConstants.KEY_TAG);
            tag(gitTagUri, "tag", Constants.HEAD);

            modifyFile(testTxt, "branched");
            addFile(testTxt);
            commitFile(testTxt, "branched", false);

            // use the same name for the new branch
            branch(branchesLocation, "tag");

            modifyFile(testTxt, "head");
            addFile(testTxt);
            commitFile(testTxt, "head", false);

            // checkout branch
            response = checkoutBranch(cloneLocation, "tag");
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            assertEquals("branched", getFileContent(testTxt));

            // checkout tag
            response = checkoutTag(cloneLocation, "tag");
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            assertEquals("tagged", getFileContent(testTxt));
        }
    }

    static JSONObject getCurrentBranch(JSONObject branches) throws JSONException {
        JSONArray branchesArray = branches.getJSONArray(ProtocolConstants.KEY_CHILDREN);
        for (int i = 0; i < branchesArray.length(); i++) {
            JSONObject branch = branchesArray.getJSONObject(i);
            if (branch.getBoolean(GitConstants.KEY_BRANCH_CURRENT))
                return branch;
        }
        return null;
    }

    private WebRequest getDeleteGitBranchRequest(String location) {
        String requestURI = toAbsoluteURI(location);
        WebRequest request = new DeleteMethodWebRequest(requestURI);
        request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
        setAuthentication(request);
        return request;
    }
}