/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.uberfire.java.nio.fs.jgit;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.hooks.PreCommitHook;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FS_POSIX;
import org.eclipse.jgit.util.ProcessResult;
import org.junit.Test;
import org.uberfire.java.nio.file.FileSystem;
import org.uberfire.java.nio.file.Path;
import static org.fest.assertions.api.Assertions.assertThat;
public class JGitFileSystemProviderHookTest extends AbstractTestInfra {
@Override
public Map<String, String> getGitPreferences() {
Map<String, String> gitPrefs = super.getGitPreferences();
gitPrefs.put("org.uberfire.nio.git.daemon.enabled",
"true");
int gitDaemonPort = findFreePort();
gitPrefs.put("org.uberfire.nio.git.daemon.port",
String.valueOf(gitDaemonPort));
try {
final File hooksDir = createTempDirectory();
gitPrefs.put("org.uberfire.nio.git.hooks",
hooksDir.getAbsolutePath());
writeMockHook(hooksDir,
"post-commit");
writeMockHook(hooksDir,
PreCommitHook.NAME);
} catch (IOException e) {
e.printStackTrace();
}
return gitPrefs;
}
@Test
public void testInstalledHook() {
final URI newRepo = URI.create("git://hook-repo-name");
final FileSystem fs = provider.newFileSystem(newRepo,
EMPTY_ENV);
assertThat(fs).isNotNull();
if (fs instanceof JGitFileSystem) {
File[] hooks = new File(((JGitFileSystem) fs).gitRepo().getRepository().getDirectory(),
"hooks").listFiles();
assertThat(hooks).isNotEmpty().isNotNull();
assertThat(hooks.length).isEqualTo(2);
boolean foundPreCommitHook = false;
boolean foundPostCommitHook = false;
for (File hook : hooks) {
if (hook.getName().equals("pre-commit")) {
foundPreCommitHook = hook.canExecute();
} else if (hook.getName().equals("post-commit")) {
foundPostCommitHook = hook.canExecute();
}
}
assertThat(foundPreCommitHook).isTrue();
assertThat(foundPostCommitHook).isTrue();
}
}
@Test
public void testExecutedPostCommitHook() throws IOException {
testHook("hook-repo-name-executed",
"post-commit",
true);
}
@Test
public void testNotSupportedPreCommitHook() throws IOException {
testHook("hook-repo-name-executed-pre-commit",
"pre-commit",
false);
}
/**
* Tests if defined hook was executed or not.
* @param gitRepoName Name of test git repository that is created for committing changes.
* @param testedHookName Tested hook name. This hook is checked for its execution.
* @param wasExecuted Expected hook execution state. If true, test expects that defined hook is executed.
* If false, test expects that defined hook is not executed.
* @throws IOException
*/
private void testHook(final String gitRepoName,
final String testedHookName,
final boolean wasExecuted) throws IOException {
final URI newRepo = URI.create("git://" + gitRepoName);
final AtomicBoolean hookExecuted = new AtomicBoolean(false);
final FileSystem fs = provider.newFileSystem(newRepo,
EMPTY_ENV);
provider.setDetectedFS(new FS_POSIX() {
@Override
public ProcessResult runHookIfPresent(Repository repox,
String hookName,
String[] args) throws JGitInternalException {
if (hookName.equals(testedHookName)) {
hookExecuted.set(true);
}
return null;
}
});
assertThat(fs).isNotNull();
final Path path = provider.getPath(URI.create("git://user_branch@" + gitRepoName + "/some/path/myfile.txt"));
final OutputStream outStream = provider.newOutputStream(path);
assertThat(outStream).isNotNull();
outStream.write("my cool content".getBytes());
outStream.close();
final InputStream inStream = provider.newInputStream(path);
final String content = new Scanner(inStream).useDelimiter("\\A").next();
inStream.close();
assertThat(content).isNotNull().isEqualTo("my cool content");
if (wasExecuted) {
assertThat(hookExecuted.get()).isTrue();
} else {
assertThat(hookExecuted.get()).isFalse();
}
}
/**
* Creates mock hook in defined hooks directory.
* @param hooksDirectory Directory in which mock hook is created.
* @param hookName Name of the created hook. This is the filename of created hook file.
* @throws FileNotFoundException
* @throws UnsupportedEncodingException
*/
private void writeMockHook(final File hooksDirectory,
final String hookName)
throws FileNotFoundException, UnsupportedEncodingException {
final PrintWriter writer = new PrintWriter(new File(hooksDirectory,
hookName),
"UTF-8");
writer.println("# something");
writer.close();
}
}