package org.gbif.checklistbank.neo; import org.gbif.api.model.checklistbank.NameUsage; import org.gbif.api.model.checklistbank.ParsedName; import org.gbif.api.vocabulary.Kingdom; import org.gbif.api.vocabulary.Origin; import org.gbif.api.vocabulary.Rank; import org.gbif.api.vocabulary.TaxonomicStatus; import org.gbif.checklistbank.cli.common.NeoConfiguration; import org.gbif.checklistbank.cli.model.GraphFormat; import org.gbif.checklistbank.nub.model.NubUsage; import org.gbif.checklistbank.nub.source.ClasspathSource; import org.gbif.utils.file.FileUtils; import org.gbif.utils.text.StringUtils; import java.io.File; import java.io.PrintWriter; import java.io.Writer; import java.util.List; import java.util.Random; import java.util.UUID; import com.google.common.base.Throwables; import com.google.common.collect.Lists; import com.google.common.io.Files; import com.codahale.metrics.MetricRegistry; import org.assertj.core.util.Preconditions; import org.junit.After; import org.junit.Ignore; import org.junit.Test; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; import static org.junit.Assert.assertEquals; public class UsageDaoTest { private final static Random RND = new Random(); UsageDao dao; @After public void destroy() { if (dao != null) { dao.closeAndDelete(); } } @Test public void tmpUsageDao() throws Exception { dao = UsageDao.temporaryDao(10); testDao(); } @Test public void persistenUsageDao() throws Exception { NeoConfiguration cfg = new NeoConfiguration(); cfg.neoRepository = Files.createTempDir(); UUID uuid = UUID.randomUUID(); MetricRegistry reg = new MetricRegistry(); dao = UsageDao.persistentDao(cfg, uuid, false, reg, true); testDao(); // close and reopen. Make sure data survived dao.close(); dao = UsageDao.persistentDao(cfg, uuid, false, reg, false); try (Transaction tx = dao.beginTx()) { NameUsage u3 = usage(300, Rank.SPECIES); Node n3 = dao.create(u3); assertEquals(u3, dao.readUsage(n3, false)); // expect previous data to remain verifyData(true, dao.getNeo().getNodeById(0), dao.getNeo().getNodeById(1)); } } @Test @Ignore("manual test to generate GML test files for rod pages forest diff tool") public void testTrees2() throws Exception { try (ClasspathSource src = new ClasspathSource(41);) { src.init(true, false, false, false); dao = src.getDao(); // add pro parte & basionym rel try (Transaction tx = dao.beginTx()) { Node ppsyn = dao.findByNameSingle("Acromantis javana"); Node acc2 = dao.findByNameSingle("Acromantis montana"); ppsyn.createRelationshipTo(acc2, RelType.PROPARTE_SYNONYM_OF); // basionym ppsyn.createRelationshipTo(acc2, RelType.BASIONYM_OF); ppsyn.addLabel(Labels.BASIONYM); tx.success(); } Writer writer = FileUtils.startNewUtf8File(new File("/Users/markus/Desktop/test.txt")); try (Transaction tx = dao.beginTx()) { dao.printTree(writer, GraphFormat.LIST, true, Rank.SUBGENUS, null); } writer.flush(); } } @Test public void testTrees() throws Exception { try (ClasspathSource src = new ClasspathSource(41);) { src.init(true, false, false, false); dao = src.getDao(); // add pro parte & basionym rel try (Transaction tx = dao.beginTx()) { Node ppsyn = dao.findByNameSingle("Acromantis javana"); Node acc2 = dao.findByNameSingle("Acromantis montana"); ppsyn.createRelationshipTo(acc2, RelType.PROPARTE_SYNONYM_OF); // basionym ppsyn.createRelationshipTo(acc2, RelType.BASIONYM_OF); ppsyn.addLabel(Labels.BASIONYM); tx.success(); } List<Rank> ranks = Lists.newArrayList((Rank) null); ranks.addAll(Rank.LINNEAN_RANKS); Writer writer = new PrintWriter(System.out); for (GraphFormat format : GraphFormat.values()) { for (int bool = 1; bool > 0; bool--) { for (Rank rank : ranks) { try (Transaction tx = dao.beginTx()) { writer.write("\n" + org.apache.commons.lang3.StringUtils.repeat("+", 60) + "\n"); writer.write("Format=" + format + ", rank=" + rank + ", fullNames=" + (bool == 1) + "\n"); writer.write(org.apache.commons.lang3.StringUtils.repeat("+", 80) + "\n"); dao.printTree(writer, format, bool == 1, rank, null); } catch (IllegalArgumentException e) { if (format != GraphFormat.GML && format != GraphFormat.TAB) { Throwables.propagate(e); } } } } } writer.flush(); } } private void verifyData(boolean expectRels, Node n1, Node n2) throws Exception { final NameUsage u2 = usage(200, Rank.SPECIES); assertEquals(usage(112, Rank.GENUS), Preconditions.checkNotNull(dao.readUsage(n1, false), "Usage 1 missing")); assertEquals(usage(112, Rank.GENUS), Preconditions.checkNotNull(dao.readUsage(n1, true), "Usage 1 missing")); assertEquals(u2, Preconditions.checkNotNull(dao.readUsage(n2, false), "Usage 2 missing")); if (expectRels) { u2.setParentKey((int) n1.getId()); // we want the canonical as the parent name! u2.setParent("Abies alba"); u2.setBasionymKey((int) n1.getId()); u2.setBasionym("Abies alba Mill."); } assertEquals(u2, Preconditions.checkNotNull(dao.readUsage(n2, true), "Usage 2 missing")); } private void testDao() throws Exception { try (Transaction tx = dao.beginTx()) { Node n1 = dao.create(usage(112, Rank.GENUS)); Node n2 = dao.create(usage(200, Rank.SPECIES)); verifyData(false, n1, n2); // now relate the 2 nodes and make sure when we read the relations the instance is changed accordingly n1.createRelationshipTo(n2, RelType.PARENT_OF); n1.createRelationshipTo(n2, RelType.BASIONYM_OF); verifyData(true, n1, n2); tx.success(); } } public static NameUsage usage(int key) { return usage(key, Rank.SPECIES); } public static NameUsage usage(int key, Rank rank) { NameUsage u = new NameUsage(); u.setKey(key); u.setKingdomKey(key); u.setParentKey(key); u.setAcceptedKey(key); u.setScientificName("Abies alba Mill."); u.setCanonicalName("Abies alba"); u.setRank(rank); u.setTaxonomicStatus(TaxonomicStatus.ACCEPTED); return u; } public static NubUsage nubusage(int key) { NubUsage u = new NubUsage(); u.usageKey = key; u.datasetKey = UUID.randomUUID(); u.kingdom = Kingdom.byNubUsageId(RND.nextInt(8)); u.origin = Origin.SOURCE; u.addRemark(StringUtils.randomSpecies()); u.parsedName = new ParsedName(); u.parsedName.setGenusOrAbove(StringUtils.randomGenus()); u.parsedName.setSpecificEpithet(StringUtils.randomEpithet()); if (key % 5 == 0) { u.rank = Rank.SUBSPECIES; u.parsedName.setInfraSpecificEpithet(StringUtils.randomEpithet()); } else { u.rank = Rank.SPECIES; } u.parsedName.setAuthorship(StringUtils.randomAuthor()); u.parsedName.setYear(StringUtils.randomSpeciesYear()); u.parsedName.setScientificName(u.parsedName.fullName()); u.status = TaxonomicStatus.ACCEPTED; return u; } }