ZEPPELIN-143: initial repo creation + tests

This commit is contained in:
Alexander Bezzubov 2015-12-01 16:01:08 +09:00
parent bdee039bfd
commit 4ef879a24e
5 changed files with 202 additions and 23 deletions

View file

@ -164,5 +164,11 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>0.27</version>
</dependency>
</dependencies>
</project>

View file

@ -17,6 +17,7 @@
package org.apache.zeppelin.notebook.repo;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
@ -26,11 +27,14 @@ import org.apache.zeppelin.notebook.Note;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
/**
* NotebookRepo that hosts all the notebook FS in a single Git repo
*
@ -46,12 +50,10 @@ import org.slf4j.LoggerFactory;
public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVersioned {
private static final Logger LOG = LoggerFactory.getLogger(GitNotebookRepo.class);
//private Repository localRepo;
private String localPath;
private Git git;
private String localPath;
// I. First usefull case:
// I. First useful case:
// start \w repo + tutorial notebook
// all modifications results in a commit
@ -59,7 +61,7 @@ public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVers
// start \wo .git
// create one
// add existing notebooks
// ..and then I...
// ..and then case I. ...
// III. Next case:
// start \w repo
@ -68,39 +70,42 @@ public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVers
public GitNotebookRepo(ZeppelinConfiguration conf) throws IOException {
super(conf);
//TODO(bzz):
// - check that ./notebooks/.git exists
// - git init
// - git add + git commit -m "Inital notebooks"
localPath = getRootDir().getName().getBaseName();
LOG.info("Opening a git repo at {}", localPath);
Repository localRepo = new FileRepository(localPath + "/.git");
localPath = getRootDir().getName().getPath();
LOG.info("Opening a git repo at '{}'", localPath);
Repository localRepo = new FileRepository(Joiner.on(File.separator).join(localPath, ".git"));
if (!localRepo.getDirectory().exists()) {
LOG.info("Git repo {} does not exist, creating a new one", localRepo.getDirectory());
localRepo.create();
}
git = new Git(localRepo);
maybeAddAndCommit(".");
}
@Override
public synchronized void save(Note note) throws IOException {
super.save(note);
maybeAddAndCommit(note.getId());
}
private void maybeAddAndCommit(String pattern) {
try {
List<DiffEntry> gitDiff = git.diff().call();
if (!gitDiff.isEmpty()) {
LOG.info("Changes found on savig notebook {}: {}", note.getId(), gitDiff);
git.add().addFilepattern(note.getId()).call();
git.commit().setMessage("Updated " + note.getId()).call();
LOG.info("Changes found for pattern {}: {}", pattern, gitDiff);
DirCache added = git.add().addFilepattern(pattern).call();
LOG.info("{} changes area about to be commited", added.getEntryCount());
git.commit().setMessage("Updated " + pattern).call();
} else {
LOG.info("No changes found on saving {}", note.getId());
LOG.info("No changes found {}", pattern);
}
} catch (GitAPIException e) {
LOG.error("Faild to save notebook {} to Git", note.getId(), e);
LOG.error("Faild to add+comit {} to Git", pattern, e);
}
}
@Override
public Note get(String noteId, String rev) throws IOException {
//TODO(alex): something instead of 'git checkout rev', which will not change-the-world
//TODO(alex): something instead of 'git checkout rev', that will not change-the-world
return super.get(noteId);
}
@ -110,4 +115,13 @@ public class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoVers
return Collections.emptyList();
}
//DI replacements for Tests
Git getGit() {
return git;
}
void setGit(Git git) {
this.git = git;
}
}

View file

@ -0,0 +1,113 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.zeppelin.notebook.repo;
import static com.google.common.truth.Truth.assertThat;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
import org.apache.zeppelin.interpreter.mock.MockInterpreter2;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.google.common.base.Joiner;
public class GitNotebookRepoTest {
private File zeppelinDir;
//private Notebook notebook;
private GitNotebookRepo notebookRepo;
private String notebooksDir;
private ZeppelinConfiguration conf;
@Before
public void setUp() throws Exception {
String zpath = System.getProperty("java.io.tmpdir")+"/ZeppelinTest_"+System.currentTimeMillis();
zeppelinDir = new File(zpath);
zeppelinDir.mkdirs();
new File(zeppelinDir, "conf").mkdirs();
notebooksDir = Joiner.on(File.separator).join(zpath, "notebook");
File notebookDir = new File(notebooksDir);
notebookDir.mkdirs();
String testNoteId = "2A94M5J1Z";
String testNoteDir = Joiner.on(File.separator).join(notebooksDir, testNoteId);
FileUtils.copyDirectory(new File(Joiner.on(File.separator).join("src", "test", "resources", testNoteId)),
new File(testNoteDir)
);
System.setProperty(ConfVars.ZEPPELIN_HOME.getVarName(), zeppelinDir.getAbsolutePath());
System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_DIR.getVarName(), notebookDir.getAbsolutePath());
System.setProperty(ConfVars.ZEPPELIN_INTERPRETERS.getVarName(), "org.apache.zeppelin.interpreter.mock.MockInterpreter1,org.apache.zeppelin.interpreter.mock.MockInterpreter2");
System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), "org.apache.zeppelin.notebook.repo.GitNotebookRepo");
MockInterpreter1.register("mock1", "org.apache.zeppelin.interpreter.mock.MockInterpreter1");
MockInterpreter2.register("mock2", "org.apache.zeppelin.interpreter.mock.MockInterpreter2");
conf = ZeppelinConfiguration.create();
/*
notebookRepo = new GitNotebookRepo(conf);
SchedulerFactory schedulerFactory = new SchedulerFactory();
InterpreterFactory replFactory = new InterpreterFactory(conf, new InterpreterOption(false), null);
JobListenerFactory jobListFactory = new JobListenerFactory() {
@Override public JobListener getParagraphJobListener(Note note) {
return null;
}
};
notebook = new Notebook(conf, notebookRepo, schedulerFactory, replFactory, jobListFactory);
*/
}
@After
public void tearDown() throws Exception {
NotebookRepoSyncTest.delete(zeppelinDir);
}
@Test
public void initNonemptyNotebookDir() throws IOException, GitAPIException {
//given - .git does not exit
File dotGit = new File(Joiner.on(File.separator).join(notebooksDir, ".git"));
assertThat(dotGit.exists()).isEqualTo(false);
//when
notebookRepo = new GitNotebookRepo(conf);
//then
Git git = notebookRepo.getGit();
assertThat(git).isNotNull();
assertThat(dotGit.exists()).isEqualTo(true);
assertThat(notebookRepo.list()).isNotEmpty();
List<DiffEntry> diff = git.diff().call();
assertThat(diff).isEmpty();
}
}

View file

@ -46,7 +46,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NotebookRepoSyncTest implements JobListenerFactory{
public class NotebookRepoSyncTest implements JobListenerFactory {
private File mainZepDir;
private ZeppelinConfiguration conf;
@ -215,7 +215,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory{
assertEquals(1, notebookRepoSync.list(1).size());
}
private void delete(File file){
static void delete(File file){
if(file.isFile()) file.delete();
else if(file.isDirectory()){
File [] files = file.listFiles();

View file

@ -0,0 +1,46 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c:%L - %m%n
#log4j.appender.stdout.layout.ConversionPattern=
#%5p [%t] (%F:%L) - %m%n
#%-4r [%t] %-5p %c %x - %m%n
#
# Root logger option
log4j.rootLogger=INFO, stdout
#mute some noisy guys
log4j.logger.org.apache.hadoop.mapred=WARN
log4j.logger.org.apache.hadoop.hive.ql=WARN
log4j.logger.org.apache.hadoop.hive.metastore=WARN
log4j.logger.org.apache.haadoop.hive.service.HiveServer=WARN
log4j.logger.org.apache.zeppelin.scheduler=WARN
log4j.logger.org.quartz=WARN
log4j.logger.DataNucleus=WARN
log4j.logger.DataNucleus.MetaData=ERROR
log4j.logger.DataNucleus.Datastore=ERROR
# Log all JDBC parameters
log4j.logger.org.hibernate.type=ALL