Package org.eclipse.jgit.internal.storage.file

Source Code of org.eclipse.jgit.internal.storage.file.GcPackRefsTest

/*
* Copyright (C) 2012, Christian Halstrick <christian.halstrick@sap.com>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials provided
*   with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
*   names of its contributors may be used to endorse or promote
*   products derived from this software without specific prior
*   written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.internal.storage.file;

import static java.lang.Integer.valueOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref.Storage;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.junit.Test;

public class GcPackRefsTest extends GcTestCase {
  @Test
  public void looseRefPacked() throws Exception {
    RevBlob a = tr.blob("a");
    tr.lightweightTag("t", a);

    gc.packRefs();
    assertSame(repo.getRef("t").getStorage(), Storage.PACKED);
  }

  @Test
  public void concurrentOnlyOneWritesPackedRefs() throws Exception {
    RevBlob a = tr.blob("a");
    tr.lightweightTag("t", a);

    final CyclicBarrier syncPoint = new CyclicBarrier(2);

    Callable<Integer> packRefs = new Callable<Integer>() {

      /** @return 0 for success, 1 in case of error when writing pack */
      public Integer call() throws Exception {
        syncPoint.await();
        try {
          gc.packRefs();
          return valueOf(0);
        } catch (IOException e) {
          return valueOf(1);
        }
      }
    };
    ExecutorService pool = Executors.newFixedThreadPool(2);
    try {
      Future<Integer> p1 = pool.submit(packRefs);
      Future<Integer> p2 = pool.submit(packRefs);
      assertEquals(1, p1.get().intValue() + p2.get().intValue());
    } finally {
      pool.shutdown();
      pool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
    }
  }

  @Test
  public void whileRefLockedRefNotPackedNoError()
      throws Exception {
    RevBlob a = tr.blob("a");
    tr.lightweightTag("t1", a);
    tr.lightweightTag("t2", a);
    LockFile refLock = new LockFile(new File(repo.getDirectory(),
        "refs/tags/t1"), repo.getFS());
    try {
      refLock.lock();
      gc.packRefs();
    } finally {
      refLock.unlock();
    }

    assertSame(repo.getRef("refs/tags/t1").getStorage(), Storage.LOOSE);
    assertSame(repo.getRef("refs/tags/t2").getStorage(), Storage.PACKED);
  }

  @Test
  public void whileRefUpdatedRefUpdateSucceeds()
      throws Exception {
    RevBlob a = tr.blob("a");
    tr.lightweightTag("t", a);
    final RevBlob b = tr.blob("b");

    final CyclicBarrier refUpdateLockedRef = new CyclicBarrier(2);
    final CyclicBarrier packRefsDone = new CyclicBarrier(2);
    ExecutorService pool = Executors.newFixedThreadPool(2);
    try {
      Future<Result> result = pool.submit(new Callable<Result>() {

        public Result call() throws Exception {
          RefUpdate update = new RefDirectoryUpdate(
              (RefDirectory) repo.getRefDatabase(),
              repo.getRef("refs/tags/t")) {
            @Override
            public boolean isForceUpdate() {
              try {
                refUpdateLockedRef.await();
                packRefsDone.await();
              } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
              } catch (BrokenBarrierException e) {
                Thread.currentThread().interrupt();
              }
              return super.isForceUpdate();
            }
          };
          update.setForceUpdate(true);
          update.setNewObjectId(b);
          return update.update();
        }
      });

      pool.submit(new Callable<Void>() {
        public Void call() throws Exception {
          refUpdateLockedRef.await();
          gc.packRefs();
          packRefsDone.await();
          return null;
        }
      });

      assertSame(result.get(), Result.FORCED);

    } finally {
      pool.shutdownNow();
      pool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
    }

    assertEquals(repo.getRef("refs/tags/t").getObjectId(), b);
  }

  @Test
  public void dontPackHEAD_nonBare() throws Exception {
    BranchBuilder bb = tr.branch("refs/heads/side");
    RevCommit first = bb.commit().add("A", "A").add("B", "B").create();
    bb.commit().add("A", "A2").add("B", "B2").create();
    Git git = Git.wrap(repo);

    // check for the unborn branch master. HEAD should point to master and
    // master doesn't exist.
    assertEquals(repo.getRef("HEAD").getTarget().getName(),
        "refs/heads/master");
    assertNull(repo.getRef("HEAD").getTarget().getObjectId());
    gc.packRefs();
    assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
    assertEquals(repo.getRef("HEAD").getTarget().getName(),
        "refs/heads/master");
    assertNull(repo.getRef("HEAD").getTarget().getObjectId());

    git.checkout().setName("refs/heads/side").call();
    gc.packRefs();
    assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);

    // check for detached HEAD
    git.checkout().setName(first.getName()).call();
    gc.packRefs();
    assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
  }

  @Test
  public void dontPackHEAD_bare() throws Exception {
    BranchBuilder bb = tr.branch("refs/heads/side");
    bb.commit().add("A", "A").add("B", "B").create();
    RevCommit second = bb.commit().add("A", "A2").add("B", "B2").create();

    // Convert the repo to be bare
    FileBasedConfig cfg = repo.getConfig();
    cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
        ConfigConstants.CONFIG_KEY_BARE, true);
    cfg.save();
    Git git = Git.open(repo.getDirectory());
    repo = (FileRepository) git.getRepository();

    // check for the unborn branch master. HEAD should point to master and
    // master doesn't exist.
    assertEquals(repo.getRef("HEAD").getTarget().getName(),
        "refs/heads/master");
    assertNull(repo.getRef("HEAD").getTarget().getObjectId());
    gc.packRefs();
    assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
    assertEquals(repo.getRef("HEAD").getTarget().getName(),
        "refs/heads/master");
    assertNull(repo.getRef("HEAD").getTarget().getObjectId());

    // check for non-detached HEAD
    repo.updateRef(Constants.HEAD).link("refs/heads/side");
    gc.packRefs();
    assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
    assertEquals(repo.getRef("HEAD").getTarget().getObjectId(),
        second.getId());
  }
}
TOP

Related Classes of org.eclipse.jgit.internal.storage.file.GcPackRefsTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.