From 438237c2b8c995d4f9562d53bfe4ea63c4442054 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 7 Sep 2019 18:59:59 +0200 Subject: [PATCH] Make testing more generic. --- org.argeo.core/pom.xml | 10 +- .../src/org/argeo/sync/fs/PathSync.java | 17 +-- .../org/argeo/sync/fs/SyncFileVisitor.java | 45 ++---- org.argeo.enterprise/bnd.bnd | 4 + org.argeo.enterprise/build.properties | 5 +- .../ext/test/AllEnterpriseTests.java | 20 +++ .../ext/test/log4j.properties | 28 ---- .../ext/test/org/argeo/fs/FsUtilsTest.java | 49 ++++++ .../argeo/osgi/useradmin/LdifParserTest.java | 30 ++-- .../osgi/useradmin/LdifUserAdminTest.java | 128 ++++++++-------- .../osgi/useradmin/UserAdminConfTest.java | 32 ++-- org.argeo.enterprise/pom.xml | 12 +- .../org/argeo/fs/BasicSyncFileVisitor.java | 139 ++++++++++++++++++ .../src/org/argeo/fs/FsUtils.java | 58 ++++++++ .../src/org/argeo/naming/DnsBrowser.java | 7 +- .../src/org/argeo/naming/LdifParser.java | 17 +-- .../osgi/internal/EnterpriseActivator.java | 21 +++ .../osgi/useradmin/AbstractUserDirectory.java | 29 +--- .../argeo/osgi/useradmin/LdapUserAdmin.java | 10 +- .../argeo/osgi/useradmin/UserAdminConf.java | 6 - .../argeo/osgi/useradmin/WcXaResource.java | 17 +-- .../transaction/simple/SimpleTransaction.java | 33 ++--- .../simple/SimpleTransactionException.java | 14 -- .../simple/SimpleTransactionManager.java | 19 +-- org.argeo.util/build.properties | 3 - ...stCase.java => CsvParserEncodingTest.java} | 16 +- .../argeo/util/CsvParserParseFileTest.java | 13 +- ...ParserTestCase.java => CsvParserTest.java} | 26 ++-- .../CsvParserWithQuotedSeparatorTest.java | 33 ++--- ...WriterTestCase.java => CsvWriterTest.java} | 20 +-- .../util/test/{Test.java => Tester.java} | 65 ++++++-- .../{TestStatus.java => TesterStatus.java} | 10 +- 32 files changed, 557 insertions(+), 379 deletions(-) create mode 100644 org.argeo.enterprise/ext/test/AllEnterpriseTests.java delete mode 100644 org.argeo.enterprise/ext/test/log4j.properties create mode 100644 org.argeo.enterprise/ext/test/org/argeo/fs/FsUtilsTest.java create mode 100644 org.argeo.enterprise/src/org/argeo/fs/BasicSyncFileVisitor.java create mode 100644 org.argeo.enterprise/src/org/argeo/fs/FsUtils.java create mode 100644 org.argeo.enterprise/src/org/argeo/osgi/internal/EnterpriseActivator.java delete mode 100644 org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionException.java rename org.argeo.util/ext/test/org/argeo/util/{CsvParserEncodingTestCase.java => CsvParserEncodingTest.java} (81%) rename org.argeo.util/ext/test/org/argeo/util/{CsvParserTestCase.java => CsvParserTest.java} (67%) rename org.argeo.util/ext/test/org/argeo/util/{CsvWriterTestCase.java => CsvWriterTest.java} (86%) rename org.argeo.util/src/org/argeo/util/test/{Test.java => Tester.java} (52%) rename org.argeo.util/src/org/argeo/util/test/{TestStatus.java => TesterStatus.java} (89%) diff --git a/org.argeo.core/pom.xml b/org.argeo.core/pom.xml index 62de67181..ed0cc927d 100644 --- a/org.argeo.core/pom.xml +++ b/org.argeo.core/pom.xml @@ -1,4 +1,7 @@ - + + 4.0.0 org.argeo.commons @@ -14,6 +17,11 @@ org.argeo.util 2.1.79-SNAPSHOT + + org.argeo.commons + org.argeo.enterprise + 2.1.79-SNAPSHOT + org.argeo.commons org.argeo.jcr diff --git a/org.argeo.core/src/org/argeo/sync/fs/PathSync.java b/org.argeo.core/src/org/argeo/sync/fs/PathSync.java index 99d5de81f..151194da6 100644 --- a/org.argeo.core/src/org/argeo/sync/fs/PathSync.java +++ b/org.argeo.core/src/org/argeo/sync/fs/PathSync.java @@ -6,19 +6,15 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.spi.FileSystemProvider; -import java.time.ZonedDateTime; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.jackrabbit.fs.DavexFsProvider; import org.argeo.ssh.Sftp; import org.argeo.sync.SyncException; -import org.argeo.util.LangUtils; +/** Synchronises two paths. */ public class PathSync implements Runnable { - private final static Log log = LogFactory.getLog(PathSync.class); - private final URI sourceUri, targetUri; + private boolean delete = false; public PathSync(URI sourceUri, URI targetUri) { this.sourceUri = sourceUri; @@ -30,11 +26,8 @@ public class PathSync implements Runnable { try { Path sourceBasePath = createPath(sourceUri); Path targetBasePath = createPath(targetUri); - SyncFileVisitor syncFileVisitor = new SyncFileVisitor(sourceBasePath, targetBasePath); - ZonedDateTime begin = ZonedDateTime.now(); + SyncFileVisitor syncFileVisitor = new SyncFileVisitor(sourceBasePath, targetBasePath, delete); Files.walkFileTree(sourceBasePath, syncFileVisitor); - if (log.isDebugEnabled()) - log.debug("Sync from " + sourceBasePath + " to " + targetBasePath + " took " + LangUtils.since(begin)); } catch (Exception e) { e.printStackTrace(); } @@ -57,8 +50,4 @@ public class PathSync implements Runnable { throw new SyncException("URI scheme not supported for " + uri); return path; } - - static enum Arg { - to, from; - } } diff --git a/org.argeo.core/src/org/argeo/sync/fs/SyncFileVisitor.java b/org.argeo.core/src/org/argeo/sync/fs/SyncFileVisitor.java index de8032004..d59a611fc 100644 --- a/org.argeo.core/src/org/argeo/sync/fs/SyncFileVisitor.java +++ b/org.argeo.core/src/org/argeo/sync/fs/SyncFileVisitor.java @@ -1,56 +1,31 @@ package org.argeo.sync.fs; -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.argeo.fs.BasicSyncFileVisitor; /** Synchronises two directory structures. */ -public class SyncFileVisitor extends SimpleFileVisitor { +public class SyncFileVisitor extends BasicSyncFileVisitor { private final static Log log = LogFactory.getLog(SyncFileVisitor.class); - private final Path sourceBasePath; - private final Path targetBasePath; - - public SyncFileVisitor(Path sourceBasePath, Path targetBasePath) { - this.sourceBasePath = sourceBasePath; - this.targetBasePath = targetBasePath; + public SyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete) { + super(sourceBasePath, targetBasePath, delete); } @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - Path targetPath = toTargetPath(dir); - Files.createDirectories(targetPath); - return FileVisitResult.CONTINUE; + protected void error(Object obj, Throwable e) { + log.error(obj, e); } @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Path targetPath = toTargetPath(file); - try { - Files.copy(file, targetPath); - if (log.isDebugEnabled()) - log.debug("Copied " + targetPath); - } catch (Exception e) { - log.error("Cannot copy " + file + " to " + targetPath, e); - } - return FileVisitResult.CONTINUE; + protected boolean isDebugEnabled() { + return log.isDebugEnabled(); } @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { - log.error("Cannot sync " + file, exc); - return FileVisitResult.CONTINUE; - } - - private Path toTargetPath(Path sourcePath) { - Path relativePath = sourceBasePath.relativize(sourcePath); - Path targetPath = targetBasePath.resolve(relativePath.toString()); - return targetPath; + protected void debug(Object obj) { + log.debug(obj); } } diff --git a/org.argeo.enterprise/bnd.bnd b/org.argeo.enterprise/bnd.bnd index 4b2eb271a..5f42f7786 100644 --- a/org.argeo.enterprise/bnd.bnd +++ b/org.argeo.enterprise/bnd.bnd @@ -1,2 +1,6 @@ +Bundle-Activator: org.argeo.osgi.internal.EnterpriseActivator +Bundle-ActivationPolicy: lazy + Import-Package: org.osgi.*;version=0.0.0,\ +!org.apache.commons.logging,\ * diff --git a/org.argeo.enterprise/build.properties b/org.argeo.enterprise/build.properties index 6fa156125..cd379dca9 100644 --- a/org.argeo.enterprise/build.properties +++ b/org.argeo.enterprise/build.properties @@ -1,7 +1,4 @@ source.. = src/,\ ext/test/ additional.bundles = org.junit,\ - org.slf4j.commons.logging,\ - org.slf4j.api,\ - org.slf4j.log4j12,\ - org.apache.log4j + org.argeo.util diff --git a/org.argeo.enterprise/ext/test/AllEnterpriseTests.java b/org.argeo.enterprise/ext/test/AllEnterpriseTests.java new file mode 100644 index 000000000..aed01f25f --- /dev/null +++ b/org.argeo.enterprise/ext/test/AllEnterpriseTests.java @@ -0,0 +1,20 @@ +import org.argeo.fs.FsUtilsTest; +import org.argeo.osgi.useradmin.LdifParserTest; +import org.argeo.osgi.useradmin.UserAdminConfTest; +import org.argeo.util.test.Tester; + +class AllEnterpriseTests { + + public static void main(String[] args) throws Exception { + Tester tester = new Tester(); + + // FS + tester.execute(FsUtilsTest.class.getName()); + + // User admin + tester.execute(LdifParserTest.class.getName()); + //tester.execute(LdifUserAdminTest.class.getName()); + tester.execute(UserAdminConfTest.class.getName()); + } + +} diff --git a/org.argeo.enterprise/ext/test/log4j.properties b/org.argeo.enterprise/ext/test/log4j.properties deleted file mode 100644 index ef735668b..000000000 --- a/org.argeo.enterprise/ext/test/log4j.properties +++ /dev/null @@ -1,28 +0,0 @@ -log4j.rootLogger=WARN, console - -## Levels -log4j.logger.org.argeo=TRACE - -log4j.logger.org.hibernate=WARN - -log4j.logger.org.springframework=WARN -#log4j.logger.org.springframework.web=DEBUG -#log4j.logger.org.springframework.jms=WARN -#log4j.logger.org.springframework.security=WARN - -log4j.logger.org.apache.activemq=WARN -log4j.logger.org.apache.activemq.transport=WARN -log4j.logger.org.apache.activemq.ActiveMQMessageConsumer=INFO -log4j.logger.org.apache.activemq.ActiveMQMessageProducer=INFO - -log4j.logger.org.apache.catalina=INFO -log4j.logger.org.apache.coyote=INFO -log4j.logger.org.apache.tomcat=INFO - -## Appenders -# console is set to be a ConsoleAppender. -log4j.appender.console=org.apache.log4j.ConsoleAppender - -# console uses PatternLayout. -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n diff --git a/org.argeo.enterprise/ext/test/org/argeo/fs/FsUtilsTest.java b/org.argeo.enterprise/ext/test/org/argeo/fs/FsUtilsTest.java new file mode 100644 index 000000000..793216b1d --- /dev/null +++ b/org.argeo.enterprise/ext/test/org/argeo/fs/FsUtilsTest.java @@ -0,0 +1,49 @@ +package org.argeo.fs; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/** {@link FsUtils} tests. */ +public class FsUtilsTest { + final static String FILE00 = "file00"; + final static String FILE01 = "file01"; + final static String SUB_DIR = "subDir"; + + public void testDelete() throws IOException { + Path dir = createDir00(); + assert Files.exists(dir); + FsUtils.delete(dir); + assert !Files.exists(dir); + } + + public void testSync() throws IOException { + Path source = createDir00(); + Path target = Files.createTempDirectory(getClass().getName()); + FsUtils.sync(source, target); + assert Files.exists(target.resolve(FILE00)); + assert Files.exists(target.resolve(SUB_DIR)); + assert Files.exists(target.resolve(SUB_DIR + File.separator + FILE01)); + FsUtils.delete(source.resolve(SUB_DIR)); + FsUtils.sync(source, target, true); + assert Files.exists(target.resolve(FILE00)); + assert !Files.exists(target.resolve(SUB_DIR)); + assert !Files.exists(target.resolve(SUB_DIR + File.separator + FILE01)); + + // clean up + FsUtils.delete(source); + FsUtils.delete(target); + + } + + Path createDir00() throws IOException { + Path base = Files.createTempDirectory(getClass().getName()); + base.toFile().deleteOnExit(); + Files.createFile(base.resolve(FILE00)).toFile().deleteOnExit(); + Path subDir = Files.createDirectories(base.resolve(SUB_DIR)); + subDir.toFile().deleteOnExit(); + Files.createFile(subDir.resolve(FILE01)).toFile().deleteOnExit(); + return base; + } +} diff --git a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java index 75bfe11ff..012a50ed1 100644 --- a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java +++ b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java @@ -13,38 +13,32 @@ import javax.naming.ldap.LdapName; import org.argeo.naming.LdapAttrs; import org.argeo.naming.LdifParser; -import junit.framework.TestCase; - -public class LdifParserTest extends TestCase implements BasicTestConstants { +/** {@link LdifParser} tests. */ +public class LdifParserTest implements BasicTestConstants { public void testBasicLdif() throws Exception { LdifParser ldifParser = new LdifParser(); - SortedMap res = ldifParser.read(getClass() - .getResourceAsStream("basic.ldif")); + SortedMap res = ldifParser.read(getClass().getResourceAsStream("basic.ldif")); LdapName rootDn = new LdapName(ROOT_USER_DN); Attributes rootAttributes = res.get(rootDn); - assertNotNull(rootAttributes); - assertEquals("Superuser", - rootAttributes.get(LdapAttrs.description.name()).get()); - byte[] rawPwEntry = (byte[]) rootAttributes.get( - LdapAttrs.userPassword.name()).get(); - assertEquals("{SHA}ieSV55Qc+eQOaYDRSha/AjzNTJE=", - new String(rawPwEntry)); + assert rootAttributes != null; + assert "Superuser".equals(rootAttributes.get(LdapAttrs.description.name()).get()); + byte[] rawPwEntry = (byte[]) rootAttributes.get(LdapAttrs.userPassword.name()).get(); + assert "{SHA}ieSV55Qc+eQOaYDRSha/AjzNTJE=".contentEquals(new String(rawPwEntry)); byte[] hashedPassword = DigestUtils.sha1("demo".getBytes()); - assertEquals("{SHA}" + Base64.getEncoder().encodeToString(hashedPassword), - new String(rawPwEntry)); + assert ("{SHA}" + Base64.getEncoder().encodeToString(hashedPassword)).equals(new String(rawPwEntry)); LdapName adminDn = new LdapName(ADMIN_GROUP_DN); Attributes adminAttributes = res.get(adminDn); - assertNotNull(adminAttributes); + assert adminAttributes != null; Attribute memberAttribute = adminAttributes.get(LdapAttrs.member.name()); - assertNotNull(memberAttribute); + assert memberAttribute != null; NamingEnumeration members = memberAttribute.getAll(); List users = new ArrayList(); while (members.hasMore()) { Object value = members.next(); users.add(value.toString()); } - assertEquals(1, users.size()); - assertEquals(rootDn, new LdapName(users.get(0))); + assert 1 == users.size(); + assert rootDn.equals(new LdapName(users.get(0))); } } diff --git a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java index 748abe835..1d6b0f3a5 100644 --- a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java +++ b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java @@ -27,7 +27,11 @@ import org.osgi.service.useradmin.User; import junit.framework.TestCase; +/** {@link LdifUserAdmin} tests. */ public class LdifUserAdminTest extends TestCase implements BasicTestConstants { + // We have to keep using JUnit because of + // https://issues.apache.org/jira/browse/SUREFIRE-1669 + final static int TM_SIMPLE = 0; final static int TM_BITRONIX = 1; @@ -37,20 +41,52 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants { private AbstractUserDirectory userAdmin; private Path tempDir; - // public void testConcurrent() throws Exception { - // } + public void setUp() { + System.out.println("Enter setUp()"); + try { + tempDir = Files.createTempDirectory(getClass().getName()); + tempDir.toFile().deleteOnExit(); + String uriProp = System.getProperty("argeo.userdirectory.uri"); + if (uriProp != null) + uri = new URI(uriProp); + else { + tempDir.toFile().deleteOnExit(); + Path ldifPath = tempDir.resolve(BASE_DN + ".ldif"); + try (InputStream in = getClass().getResource("basic.ldif").openStream()) { + Files.copy(in, ldifPath); + } + uri = ldifPath.toUri(); + } + + // Init transaction manager + if (TM_SIMPLE == tmType) { + tm = new SimpleTransactionManager(); + } +// else if (TM_BITRONIX == tmType) { +// bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration(); +// tmConf.setServerId(UUID.randomUUID().toString()); +// tmConf.setLogPart1Filename(new File(tempDir.toFile(), "btm1.tlog").getAbsolutePath()); +// tmConf.setLogPart2Filename(new File(tempDir.toFile(), "btm2.tlog").getAbsolutePath()); +// tm = TransactionManagerServices.getTransactionManager(); +// } + + userAdmin = initUserAdmin(uri, tm); + } catch (Exception e) { + throw new RuntimeException(e); + } + } public void testEdition() throws Exception { User demoUser = (User) userAdmin.getRole(DEMO_USER_DN); - assertNotNull(demoUser); + assert demoUser != null; tm.begin(); String newName = "demo"; demoUser.getProperties().put("cn", newName); - assertEquals(newName, demoUser.getProperties().get("cn")); + assert newName.equals(demoUser.getProperties().get("cn")); tm.commit(); persistAndRestart(); - assertEquals(newName, demoUser.getProperties().get("cn")); + assert newName.equals(demoUser.getProperties().get("cn")); tm.begin(); userAdmin.removeRole(DEMO_USER_DN); @@ -59,59 +95,59 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants { // check data Role[] search = userAdmin.getRoles("(objectclass=inetOrgPerson)"); - assertEquals(1, search.length); + assert 1 == search.length; Group editorGroup = (Group) userAdmin.getRole(EDITORS_GROUP_DN); - assertNotNull(editorGroup); + assert editorGroup != null; Role[] members = editorGroup.getMembers(); - assertEquals(1, members.length); + assert 1 == members.length; } public void testRetrieve() throws Exception { // users User rootUser = (User) userAdmin.getRole(ROOT_USER_DN); - assertNotNull(rootUser); + assert rootUser != null; User demoUser = (User) userAdmin.getRole(DEMO_USER_DN); - assertNotNull(demoUser); + assert demoUser != null; // groups Group adminGroup = (Group) userAdmin.getRole(ADMIN_GROUP_DN); - assertNotNull(adminGroup); + assert adminGroup != null; Role[] members = adminGroup.getMembers(); - assertEquals(1, members.length); - assertEquals(rootUser, members[0]); + assert 1 == members.length; + assert rootUser.equals(members[0]); Group editorGroup = (Group) userAdmin.getRole(EDITORS_GROUP_DN); - assertNotNull(editorGroup); + assert editorGroup != null; members = editorGroup.getMembers(); - assertEquals(2, members.length); - assertEquals(adminGroup, members[0]); - assertEquals(demoUser, members[1]); + assert 2 == members.length; + assert adminGroup.equals(members[0]); + assert demoUser.equals(members[1]); Authorization rootAuth = userAdmin.getAuthorization(rootUser); List rootRoles = Arrays.asList(rootAuth.getRoles()); - assertEquals(3, rootRoles.size()); - assertTrue(rootRoles.contains(ROOT_USER_DN)); - assertTrue(rootRoles.contains(ADMIN_GROUP_DN)); - assertTrue(rootRoles.contains(EDITORS_GROUP_DN)); + assert 3 == rootRoles.size(); + assert rootRoles.contains(ROOT_USER_DN); + assert rootRoles.contains(ADMIN_GROUP_DN); + assert rootRoles.contains(EDITORS_GROUP_DN); // properties - assertEquals("root@localhost", rootUser.getProperties().get("mail")); + assert "root@localhost".equals(rootUser.getProperties().get("mail")); // credentials byte[] hashedPassword = ("{SHA}" + Base64.getEncoder().encodeToString(DigestUtils.sha1("demo".getBytes()))) .getBytes(); - assertTrue(rootUser.hasCredential(LdapAttrs.userPassword.name(), hashedPassword)); - assertTrue(demoUser.hasCredential(LdapAttrs.userPassword.name(), hashedPassword)); + assert rootUser.hasCredential(LdapAttrs.userPassword.name(), hashedPassword); + assert demoUser.hasCredential(LdapAttrs.userPassword.name(), hashedPassword); // search Role[] search = userAdmin.getRoles(null); - assertEquals(4, search.length); + assert 4 == search.length; search = userAdmin.getRoles("(objectClass=groupOfNames)"); - assertEquals(2, search.length); + assert 2 == search.length; search = userAdmin.getRoles("(objectclass=inetOrgPerson)"); - assertEquals(2, search.length); + assert 2 == search.length; search = userAdmin.getRoles("(&(objectclass=inetOrgPerson)(uid=demo))"); - assertEquals(1, search.length); + assert 1 == search.length; } public void testReadWriteRead() throws Exception { @@ -129,43 +165,12 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants { ((LdifUserAdmin) userAdmin).load(in); } Role[] search = userAdmin.getRoles(null); - assertEquals(4, search.length); + assert 4 == search.length; } else { // test not relevant for LDAP } } - @Override - protected void setUp() throws Exception { - tempDir = Files.createTempDirectory(getClass().getName()); - tempDir.toFile().deleteOnExit(); - String uriProp = System.getProperty("argeo.userdirectory.uri"); - if (uriProp != null) - uri = new URI(uriProp); - else { - tempDir.toFile().deleteOnExit(); - Path ldifPath = tempDir.resolve(BASE_DN + ".ldif"); - try (InputStream in = getClass().getResource("basic.ldif").openStream()) { - Files.copy(in, ldifPath); - } - uri = ldifPath.toUri(); - } - - // Init transaction manager - if (TM_SIMPLE == tmType) { - tm = new SimpleTransactionManager(); - } -// else if (TM_BITRONIX == tmType) { -// bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration(); -// tmConf.setServerId(UUID.randomUUID().toString()); -// tmConf.setLogPart1Filename(new File(tempDir.toFile(), "btm1.tlog").getAbsolutePath()); -// tmConf.setLogPart2Filename(new File(tempDir.toFile(), "btm2.tlog").getAbsolutePath()); -// tm = TransactionManagerServices.getTransactionManager(); -// } - - userAdmin = initUserAdmin(uri, tm); - } - private AbstractUserDirectory initUserAdmin(URI uri, TransactionManager tm) { Dictionary props = new Hashtable<>(); props.put(UserAdminConf.uri.name(), uri.toString()); @@ -194,8 +199,7 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants { userAdmin = initUserAdmin(uri, tm); } - @Override - protected void tearDown() throws Exception { + public void tearDown() throws Exception { // if (TM_BITRONIX == tmType) { // EhCacheXAResourceProducer.unregisterXAResource(UserDirectory.class.getName(), userAdmin.getXaResource()); // ((BitronixTransactionManager) tm).shutdown(); diff --git a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/UserAdminConfTest.java b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/UserAdminConfTest.java index d69cae4c0..77a35f424 100644 --- a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/UserAdminConfTest.java +++ b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/UserAdminConfTest.java @@ -6,48 +6,48 @@ import static org.argeo.osgi.useradmin.UserAdminConf.uriAsProperties; import java.net.URI; import java.util.Dictionary; -import junit.framework.TestCase; - -public class UserAdminConfTest extends TestCase { +/** {@link UserAdminConf} tests. */ +public class UserAdminConfTest { public void testUriFormat() throws Exception { // LDAP URI uriIn = new URI("ldap://" + "uid=admin,ou=system:secret@localhost:10389" + "/dc=example,dc=com" + "?readOnly=false&userObjectClass=person"); Dictionary props = uriAsProperties(uriIn.toString()); System.out.println(props); - assertEquals("dc=example,dc=com", props.get(UserAdminConf.baseDn.name())); - assertEquals("false", props.get(UserAdminConf.readOnly.name())); - assertEquals("person", props.get(UserAdminConf.userObjectClass.name())); + assert "dc=example,dc=com".equals(props.get(UserAdminConf.baseDn.name())); + assert "false".equals(props.get(UserAdminConf.readOnly.name())); + assert "person".equals(props.get(UserAdminConf.userObjectClass.name())); URI uriOut = propertiesAsUri(props); System.out.println(uriOut); - assertEquals("/dc=example,dc=com?userObjectClass=person&readOnly=false", uriOut.toString()); + assert "/dc=example,dc=com?userObjectClass=person&readOnly=false".equals(uriOut.toString()); // File uriIn = new URI("file://some/dir/dc=example,dc=com.ldif"); props = uriAsProperties(uriIn.toString()); System.out.println(props); - assertEquals("dc=example,dc=com", props.get(UserAdminConf.baseDn.name())); + assert "dc=example,dc=com".equals(props.get(UserAdminConf.baseDn.name())); // Base configuration uriIn = new URI("/dc=example,dc=com.ldif?readOnly=true&userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles"); props = uriAsProperties(uriIn.toString()); System.out.println(props); - assertEquals("dc=example,dc=com", props.get(UserAdminConf.baseDn.name())); - assertEquals("true", props.get(UserAdminConf.readOnly.name())); - assertEquals("ou=CoWorkers,ou=People", props.get(UserAdminConf.userBase.name())); - assertEquals("ou=Roles", props.get(UserAdminConf.groupBase.name())); + assert "dc=example,dc=com".equals(props.get(UserAdminConf.baseDn.name())); + assert "true".equals(props.get(UserAdminConf.readOnly.name())); + assert "ou=CoWorkers,ou=People".equals(props.get(UserAdminConf.userBase.name())); + assert "ou=Roles".equals(props.get(UserAdminConf.groupBase.name())); uriOut = propertiesAsUri(props); System.out.println(uriOut); - assertEquals("/dc=example,dc=com?userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles&readOnly=true", uriOut.toString()); + assert "/dc=example,dc=com?userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles&readOnly=true" + .equals(uriOut.toString()); // OS uriIn = new URI("os:///dc=example,dc=com"); props = uriAsProperties(uriIn.toString()); System.out.println(props); - assertEquals("dc=example,dc=com", props.get(UserAdminConf.baseDn.name())); - assertEquals("true", props.get(UserAdminConf.readOnly.name())); + assert "dc=example,dc=com".equals(props.get(UserAdminConf.baseDn.name())); + assert "true".equals(props.get(UserAdminConf.readOnly.name())); uriOut = propertiesAsUri(props); System.out.println(uriOut); - assertEquals("/dc=example,dc=com?readOnly=true", uriOut.toString()); + assert "/dc=example,dc=com?readOnly=true".equals(uriOut.toString()); } } diff --git a/org.argeo.enterprise/pom.xml b/org.argeo.enterprise/pom.xml index a5cc1aa7e..6dc4cc1c5 100644 --- a/org.argeo.enterprise/pom.xml +++ b/org.argeo.enterprise/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.argeo.commons @@ -9,4 +11,12 @@ org.argeo.enterprise Commons Enterprise + + + org.argeo.commons + org.argeo.util + 2.1.79-SNAPSHOT + test + + \ No newline at end of file diff --git a/org.argeo.enterprise/src/org/argeo/fs/BasicSyncFileVisitor.java b/org.argeo.enterprise/src/org/argeo/fs/BasicSyncFileVisitor.java new file mode 100644 index 000000000..6c9f39913 --- /dev/null +++ b/org.argeo.enterprise/src/org/argeo/fs/BasicSyncFileVisitor.java @@ -0,0 +1,139 @@ +package org.argeo.fs; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; + +/** Synchronises two directory structures. */ +public class BasicSyncFileVisitor extends SimpleFileVisitor { + // TODO make it configurable + private boolean debug = true; + + private final Path sourceBasePath; + private final Path targetBasePath; + private final boolean delete; + + public BasicSyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete) { + this.sourceBasePath = sourceBasePath; + this.targetBasePath = targetBasePath; + this.delete = delete; + } + + @Override + public FileVisitResult preVisitDirectory(Path sourceDir, BasicFileAttributes attrs) throws IOException { + Path targetDir = toTargetPath(sourceDir); + Files.createDirectories(targetDir); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path sourceDir, IOException exc) throws IOException { + if (delete) { + Path targetDir = toTargetPath(sourceDir); + for (Path targetPath : Files.newDirectoryStream(targetDir)) { + Path sourcePath = sourceDir.resolve(targetPath.getFileName()); + if (!Files.exists(sourcePath)) { + try { + FsUtils.delete(targetPath); + deleted(targetPath); + } catch (Exception e) { + deleteFailed(targetPath, exc); + } + } + } + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { + Path targetFile = toTargetPath(sourceFile); + try { + if (!Files.exists(targetFile)) { + Files.copy(sourceFile, targetFile); + copied(sourceFile, targetFile); + } else { + if (shouldOverwrite(sourceFile, targetFile)) { + Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING); + } + } + } catch (Exception e) { + copyFailed(sourceFile, targetFile, e); + } + return FileVisitResult.CONTINUE; + } + + protected boolean shouldOverwrite(Path sourceFile, Path targetFile) throws IOException { + long sourceSize = Files.size(sourceFile); + long targetSize = Files.size(targetFile); + if (sourceSize != targetSize) { + return true; + } + FileTime sourceLastModif = Files.getLastModifiedTime(sourceFile); + FileTime targetLastModif = Files.getLastModifiedTime(targetFile); + if (sourceLastModif.compareTo(targetLastModif) > 0) + return true; + return shouldOverwriteLaterSameSize(sourceFile, targetFile); + } + + protected boolean shouldOverwriteLaterSameSize(Path sourceFile, Path targetFile) { + return false; + } + +// @Override +// public FileVisitResult visitFileFailed(Path sourceFile, IOException exc) throws IOException { +// error("Cannot sync " + sourceFile, exc); +// return FileVisitResult.CONTINUE; +// } + + private Path toTargetPath(Path sourcePath) { + Path relativePath = sourceBasePath.relativize(sourcePath); + Path targetPath = targetBasePath.resolve(relativePath.toString()); + return targetPath; + } + + public Path getSourceBasePath() { + return sourceBasePath; + } + + public Path getTargetBasePath() { + return targetBasePath; + } + + protected void copied(Path sourcePath, Path targetPath) { + if (isDebugEnabled()) + debug("Copied " + sourcePath + " to " + targetPath); + } + + protected void copyFailed(Path sourcePath, Path targetPath, Exception e) { + error("Cannot copy " + sourcePath + " to " + targetPath, e); + } + + protected void deleted(Path targetPath) { + if (isDebugEnabled()) + debug("Deleted " + targetPath); + } + + protected void deleteFailed(Path targetPath, Exception e) { + error("Cannot delete " + targetPath, e); + } + + /** Log error. */ + protected void error(Object obj, Throwable e) { + System.err.println(obj); + e.printStackTrace(); + } + + protected boolean isDebugEnabled() { + return debug; + } + + protected void debug(Object obj) { + System.out.println(obj); + } +} diff --git a/org.argeo.enterprise/src/org/argeo/fs/FsUtils.java b/org.argeo.enterprise/src/org/argeo/fs/FsUtils.java new file mode 100644 index 000000000..6fc7bd25d --- /dev/null +++ b/org.argeo.enterprise/src/org/argeo/fs/FsUtils.java @@ -0,0 +1,58 @@ +package org.argeo.fs; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +/** Utilities around the standard Java file abstractions. */ +public class FsUtils { + /** Sync a source path with a target path. */ + public static void sync(Path sourceBasePath, Path targetBasePath) { + sync(sourceBasePath, targetBasePath, false); + } + + /** Sync a source path with a target path. */ + public static void sync(Path sourceBasePath, Path targetBasePath, boolean delete) { + sync(new BasicSyncFileVisitor(sourceBasePath, targetBasePath, delete)); + } + + public static void sync(BasicSyncFileVisitor syncFileVisitor) { + try { + Files.walkFileTree(syncFileVisitor.getSourceBasePath(), syncFileVisitor); + } catch (Exception e) { + throw new RuntimeException("Cannot sync " + syncFileVisitor.getSourceBasePath() + " with " + + syncFileVisitor.getTargetBasePath(), e); + } + } + + /** Deletes this path, recursively if needed. */ + public static void delete(Path path) { + try { + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult postVisitDirectory(Path directory, IOException e) throws IOException { + if (e != null) + throw e; + Files.delete(directory); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new RuntimeException("Cannot delete " + path, e); + } + } + + /** Singleton. */ + private FsUtils() { + } + +} diff --git a/org.argeo.enterprise/src/org/argeo/naming/DnsBrowser.java b/org.argeo.enterprise/src/org/argeo/naming/DnsBrowser.java index 7aadd64d8..62667c518 100644 --- a/org.argeo.enterprise/src/org/argeo/naming/DnsBrowser.java +++ b/org.argeo.enterprise/src/org/argeo/naming/DnsBrowser.java @@ -21,12 +21,7 @@ import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - public class DnsBrowser implements Closeable { - private final static Log log = LogFactory.getLog(DnsBrowser.class); - private final DirContext initialCtx; public DnsBrowser() throws NamingException { @@ -140,7 +135,7 @@ public class DnsBrowser implements Closeable { try { initialCtx.close(); } catch (NamingException e) { - log.error("Cannot close context", e); + // silent } } diff --git a/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java b/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java index 86392b345..cc1957058 100644 --- a/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java +++ b/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java @@ -22,13 +22,10 @@ import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.osgi.useradmin.UserDirectoryException; /** Basic LDIF parser. */ public class LdifParser { - private final static Log log = LogFactory.getLog(LdifParser.class); private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; protected Attributes addAttributes(SortedMap res, int lineNumber, LdapName currentDn, @@ -43,8 +40,6 @@ public class LdifParser { "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn + " (shortly before line " + lineNumber + " in LDIF file)"); Attributes previous = res.put(currentDn, currentAttributes); - if (log.isTraceEnabled()) - log.trace("Added " + currentDn); return previous; } catch (NamingException e) { throw new UserDirectoryException("Cannot add " + currentDn, e); @@ -59,8 +54,7 @@ public class LdifParser { try { in.close(); } catch (IOException e) { - if (log.isTraceEnabled()) - log.error("Cannot close stream", e); + // silent } } } @@ -126,8 +120,8 @@ public class LdifParser { // Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes); if (previous != null) { - log.warn("There was already an entry with DN " + currentDn - + ", which has been discarded by a subsequent one."); +// log.warn("There was already an entry with DN " + currentDn +// + ", which has been discarded by a subsequent one."); } } @@ -136,7 +130,7 @@ public class LdifParser { currentDn = new LdapName(attributeValue.toString()); currentAttributes = new BasicAttributes(true); } catch (InvalidNameException e) { - log.error(attributeValue + " not a valid DN, skipping the entry."); +// log.error(attributeValue + " not a valid DN, skipping the entry."); currentDn = null; currentAttributes = null; } @@ -159,8 +153,7 @@ public class LdifParser { try { reader.close(); } catch (IOException e) { - if (log.isTraceEnabled()) - log.error("Cannot close stream", e); + // silent } } return res; diff --git a/org.argeo.enterprise/src/org/argeo/osgi/internal/EnterpriseActivator.java b/org.argeo.enterprise/src/org/argeo/osgi/internal/EnterpriseActivator.java new file mode 100644 index 000000000..03054828c --- /dev/null +++ b/org.argeo.enterprise/src/org/argeo/osgi/internal/EnterpriseActivator.java @@ -0,0 +1,21 @@ +package org.argeo.osgi.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * Called to gather information about the OSGi runtime. Should not activate + * anything else that canonical monitoring services (not creating implicit + * APIs), which is the responsibility of higher levels.. + */ +public class EnterpriseActivator implements BundleActivator { + + @Override + public void start(BundleContext context) throws Exception { + } + + @Override + public void stop(BundleContext context) throws Exception { + } + +} diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java index 385ea740e..a39743897 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java @@ -31,8 +31,6 @@ import javax.transaction.SystemException; import javax.transaction.Transaction; import javax.transaction.TransactionManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.naming.LdapAttrs; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; @@ -47,8 +45,6 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory static final String SHARED_STATE_USERNAME = "javax.security.auth.login.name"; static final String SHARED_STATE_PASSWORD = "javax.security.auth.login.password"; - private final static Log log = LogFactory.getLog(AbstractUserDirectory.class); - private final Hashtable properties; private final LdapName baseDn, userBaseDn, groupBaseDn; private final String userObjectClass, userBase, groupObjectClass, groupBase; @@ -187,8 +183,6 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory LdapName groupDn = new LdapName(value.toString()); DirectoryUser group = doGetRole(groupDn); allRoles.add(group); - if (log.isTraceEnabled()) - log.trace("Add memberOf " + groupDn); } } catch (Exception e) { throw new UserDirectoryException("Cannot get memberOf groups for " + user, e); @@ -198,8 +192,6 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory // TODO check for loops DirectoryUser group = doGetRole(groupDn); allRoles.add(group); - if (log.isTraceEnabled()) - log.trace("Add direct group " + groupDn); collectRoles(group, allRoles); } } @@ -262,23 +254,14 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory doGetUser(key, value, collectedUsers); } else { throw new UserDirectoryException("Key cannot be null"); - // // try dn - // DirectoryUser user = null; - // try { - // user = (DirectoryUser) getRole(value); - // if (user != null) - // collectedUsers.add(user); - // } catch (Exception e) { - // // silent - // } - // // try all indexes - // for (String attr : getIndexedUserProperties()) - // doGetUser(attr, value, collectedUsers); } - if (collectedUsers.size() == 1) + + if (collectedUsers.size() == 1) { return collectedUsers.get(0); - else if (collectedUsers.size() > 1) - log.warn(collectedUsers.size() + " users for " + (key != null ? key + "=" : "") + value); + } else if (collectedUsers.size() > 1) { + // log.warn(collectedUsers.size() + " users for " + (key != null ? key + "=" : + // "") + value); + } return null; } diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdapUserAdmin.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdapUserAdmin.java index 10a75feb0..58f6eb1fa 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdapUserAdmin.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdapUserAdmin.java @@ -22,8 +22,6 @@ import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapName; import javax.transaction.TransactionManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.naming.LdapAttrs; import org.osgi.framework.Filter; import org.osgi.service.useradmin.Role; @@ -34,8 +32,6 @@ import org.osgi.service.useradmin.User; * and an open transaction for write access. */ public class LdapUserAdmin extends AbstractUserDirectory { - private final static Log log = LogFactory.getLog(LdapUserAdmin.class); - private InitialLdapContext initialLdapContext = null; public LdapUserAdmin(Dictionary properties) { @@ -74,7 +70,7 @@ public class LdapUserAdmin extends AbstractUserDirectory { // tls.close(); initialLdapContext.close(); } catch (NamingException e) { - log.error("Cannot destroy LDAP user admin", e); + e.printStackTrace(); } } @@ -128,8 +124,6 @@ public class LdapUserAdmin extends AbstractUserDirectory { } catch (NameNotFoundException e) { throw e; } catch (NamingException e) { - if (log.isTraceEnabled()) - log.error("Cannot get role: " + name, e); return null; } } @@ -160,7 +154,7 @@ public class LdapUserAdmin extends AbstractUserDirectory { || objectClassAttr.contains(getUserObjectClass().toLowerCase())) role = new LdifUser(this, dn, attrs); else { - log.warn("Unsupported LDAP type for " + searchResult.getName()); +// log.warn("Unsupported LDAP type for " + searchResult.getName()); continue results; } res.add(role); diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java index 37d633920..bb7345f0b 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java @@ -15,8 +15,6 @@ import javax.naming.Context; import javax.naming.NamingException; import javax.naming.ldap.LdapName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.naming.DnsBrowser; import org.argeo.naming.NamingUtils; import org.osgi.framework.Constants; @@ -51,7 +49,6 @@ public enum UserAdminConf { realm(null); public final static String FACTORY_PID = "org.argeo.osgi.useradmin.config"; - private final static Log log = LogFactory.getLog(UserAdminConf.class); public final static String SCHEME_LDAP = "ldap"; public final static String SCHEME_FILE = "file"; @@ -221,8 +218,6 @@ public enum UserAdminConf { } URI convertedUri = new URI( SCHEME_LDAP + "://" + ldapHostsStr + "/" + IpaUtils.domainToUserDirectoryConfigPath(kerberosRealm)); - if (log.isDebugEnabled()) - log.debug("Converted " + uri + " to " + convertedUri); return convertedUri; } catch (NamingException | IOException | URISyntaxException e) { throw new UserDirectoryException("cannot convert IPA uri " + uri, e); @@ -248,7 +243,6 @@ public enum UserAdminConf { try { hostname = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { - log.warn("Using localhost as hostname", e); hostname = "localhost.localdomain"; } int dotIdx = hostname.indexOf('.'); diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/WcXaResource.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/WcXaResource.java index a6048fdca..525176d96 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/WcXaResource.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/WcXaResource.java @@ -7,13 +7,8 @@ import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - /** {@link XAResource} for a user directory being edited. */ class WcXaResource implements XAResource { - private final static Log log = LogFactory.getLog(WcXaResource.class); - private final AbstractUserDirectory userDirectory; private Map workingCopies = new HashMap(); @@ -28,11 +23,9 @@ class WcXaResource implements XAResource { public synchronized void start(Xid xid, int flags) throws XAException { if (editingXid != null) throw new UserDirectoryException("Already editing " + editingXid); - UserDirectoryWorkingCopy wc = workingCopies.put(xid, - new UserDirectoryWorkingCopy()); + UserDirectoryWorkingCopy wc = workingCopies.put(xid, new UserDirectoryWorkingCopy()); if (wc != null) - throw new UserDirectoryException( - "There is already a working copy for " + xid); + throw new UserDirectoryException("There is already a working copy for " + xid); this.editingXid = xid; } @@ -50,8 +43,7 @@ class WcXaResource implements XAResource { return null; UserDirectoryWorkingCopy wc = workingCopies.get(editingXid); if (wc == null) - throw new UserDirectoryException("No working copy found for " - + editingXid); + throw new UserDirectoryException("No working copy found for " + editingXid); return wc; } @@ -70,7 +62,6 @@ class WcXaResource implements XAResource { try { userDirectory.prepare(wc); } catch (Exception e) { - log.error("Cannot prepare " + xid, e); throw new XAException(XAException.XAER_RMERR); } return XA_OK; @@ -87,7 +78,6 @@ class WcXaResource implements XAResource { userDirectory.prepare(wc); userDirectory.commit(wc); } catch (Exception e) { - log.error("Cannot commit " + xid, e); throw new XAException(XAException.XAER_RMERR); } finally { cleanUp(xid); @@ -100,7 +90,6 @@ class WcXaResource implements XAResource { checkXid(xid); userDirectory.rollback(wc(xid)); } catch (Exception e) { - log.error("Cannot rollback " + xid, e); throw new XAException(XAException.XAER_RMERR); } finally { cleanUp(xid); diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java index fbb138668..43d4cd91c 100644 --- a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java +++ b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java @@ -14,12 +14,8 @@ import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - +/** Simple implementation of an XA {@link Transaction}. */ class SimpleTransaction implements Transaction, Status { - private final static Log log = LogFactory.getLog(SimpleTransaction.class); - private final Xid xid; private int status = Status.STATUS_ACTIVE; private final List xaResources = new ArrayList(); @@ -32,8 +28,7 @@ class SimpleTransaction implements Transaction, Status { } @Override - public synchronized void commit() throws RollbackException, - HeuristicMixedException, HeuristicRollbackException, + public synchronized void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException { status = STATUS_PREPARING; for (XAResource xaRes : xaResources) { @@ -43,7 +38,7 @@ class SimpleTransaction implements Transaction, Status { xaRes.prepare(xid); } catch (XAException e) { status = STATUS_MARKED_ROLLBACK; - log.error("Cannot prepare " + xaRes + " for " + xid, e); + error("Cannot prepare " + xaRes + " for " + xid, e); } } if (status == STATUS_MARKED_ROLLBACK) { @@ -60,7 +55,7 @@ class SimpleTransaction implements Transaction, Status { xaRes.commit(xid, false); } catch (XAException e) { status = STATUS_MARKED_ROLLBACK; - log.error("Cannot prepare " + xaRes + " for " + xid, e); + error("Cannot prepare " + xaRes + " for " + xid, e); } } if (status == STATUS_MARKED_ROLLBACK) { @@ -70,28 +65,23 @@ class SimpleTransaction implements Transaction, Status { // complete status = STATUS_COMMITTED; - if (log.isTraceEnabled()) - log.trace("COMMITTED " + xid); clearResources(XAResource.TMSUCCESS); transactionManager.unregister(xid); } @Override - public synchronized void rollback() throws IllegalStateException, - SystemException { + public synchronized void rollback() throws IllegalStateException, SystemException { status = STATUS_ROLLING_BACK; for (XAResource xaRes : xaResources) { try { xaRes.rollback(xid); } catch (XAException e) { - log.error("Cannot rollback " + xaRes + " for " + xid, e); + error("Cannot rollback " + xaRes + " for " + xid, e); } } // complete status = STATUS_ROLLEDBACK; - if (log.isTraceEnabled()) - log.trace("ROLLEDBACK " + xid); clearResources(XAResource.TMFAIL); transactionManager.unregister(xid); } @@ -104,7 +94,7 @@ class SimpleTransaction implements Transaction, Status { xaRes.start(getXid(), XAResource.TMNOFLAGS); return true; } catch (XAException e) { - log.error("Cannot enlist " + xaRes, e); + error("Cannot enlist " + xaRes, e); return false; } } else @@ -118,7 +108,7 @@ class SimpleTransaction implements Transaction, Status { try { xaRes.end(getXid(), flag); } catch (XAException e) { - log.error("Cannot delist " + xaRes, e); + error("Cannot delist " + xaRes, e); return false; } return true; @@ -131,11 +121,16 @@ class SimpleTransaction implements Transaction, Status { try { xaRes.end(getXid(), flag); } catch (XAException e) { - log.error("Cannot end " + xaRes, e); + error("Cannot end " + xaRes, e); } xaResources.clear(); } + protected void error(Object obj, Exception e) { + System.err.println(obj); + e.printStackTrace(); + } + @Override public synchronized int getStatus() throws SystemException { return status; diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionException.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionException.java deleted file mode 100644 index d00def966..000000000 --- a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.argeo.transaction.simple; - -public class SimpleTransactionException extends RuntimeException { - private static final long serialVersionUID = -7465792070797750212L; - - public SimpleTransactionException(String message) { - super(message); - } - - public SimpleTransactionException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java index fef728146..7dcf7d99a 100644 --- a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java +++ b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java @@ -18,12 +18,11 @@ import javax.transaction.TransactionSynchronizationRegistry; import javax.transaction.UserTransaction; import javax.transaction.xa.Xid; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - +/** + * Simple implementation of an XA {@link TransactionManager} and + * {@link UserTransaction}. + */ public class SimpleTransactionManager implements TransactionManager, UserTransaction { - private final static Log log = LogFactory.getLog(SimpleTransactionManager.class); - private ThreadLocal current = new ThreadLocal(); private Map knownTransactions = Collections @@ -37,8 +36,6 @@ public class SimpleTransactionManager implements TransactionManager, UserTransac SimpleTransaction transaction = new SimpleTransaction(this); knownTransactions.put(transaction.getXid(), transaction); current.set(transaction); - if (log.isTraceEnabled()) - log.trace("STARTED " + transaction.getXid()); } @Override @@ -123,7 +120,7 @@ public class SimpleTransactionManager implements TransactionManager, UserTransac return null; return getCurrent().getXid(); } catch (SystemException e) { - throw new SimpleTransactionException("Cannot get transaction key", e); + throw new IllegalStateException("Cannot get transaction key", e); } } @@ -147,7 +144,7 @@ public class SimpleTransactionManager implements TransactionManager, UserTransac try { return getStatus(); } catch (SystemException e) { - throw new SimpleTransactionException("Cannot get status", e); + throw new IllegalStateException("Cannot get status", e); } } @@ -156,7 +153,7 @@ public class SimpleTransactionManager implements TransactionManager, UserTransac try { return getStatus() == Status.STATUS_MARKED_ROLLBACK; } catch (SystemException e) { - throw new SimpleTransactionException("Cannot get status", e); + throw new IllegalStateException("Cannot get status", e); } } @@ -165,7 +162,7 @@ public class SimpleTransactionManager implements TransactionManager, UserTransac try { getCurrent().setRollbackOnly(); } catch (Exception e) { - throw new SimpleTransactionException("Cannot set rollback only", e); + throw new IllegalStateException("Cannot set rollback only", e); } } diff --git a/org.argeo.util/build.properties b/org.argeo.util/build.properties index 9a8006a7c..d34068df7 100644 --- a/org.argeo.util/build.properties +++ b/org.argeo.util/build.properties @@ -1,6 +1,3 @@ source.. = src/,\ ext/test/ output.. = bin/ -additional.bundles = org.junit,\ - org.slf4j.commons.logging,\ - org.apache.log4j diff --git a/org.argeo.util/ext/test/org/argeo/util/CsvParserEncodingTestCase.java b/org.argeo.util/ext/test/org/argeo/util/CsvParserEncodingTest.java similarity index 81% rename from org.argeo.util/ext/test/org/argeo/util/CsvParserEncodingTestCase.java rename to org.argeo.util/ext/test/org/argeo/util/CsvParserEncodingTest.java index 111a8738c..72f2932d3 100644 --- a/org.argeo.util/ext/test/org/argeo/util/CsvParserEncodingTestCase.java +++ b/org.argeo.util/ext/test/org/argeo/util/CsvParserEncodingTest.java @@ -19,9 +19,8 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; -import junit.framework.TestCase; - -public class CsvParserEncodingTestCase extends TestCase { +/** Tests that {@link CsvParser} can deal properly with encodings. */ +public class CsvParserEncodingTest { private String iso = "ISO-8859-1"; private String utf8 = "UTF-8"; @@ -36,12 +35,11 @@ public class CsvParserEncodingTestCase extends TestCase { InputStream inIso = new ByteArrayInputStream(isoBytes); CsvParser csvParser = new CsvParser() { - protected void processLine(Integer lineNumber, List header, - List tokens) { - assertEquals(header.size(), tokens.size()); - assertEquals(2, tokens.size()); - assertEquals("áéíóúñ", tokens.get(0)); - assertEquals("éééé", tokens.get(1)); + protected void processLine(Integer lineNumber, List header, List tokens) { + assert header.size() == tokens.size(); + assert 2 == tokens.size(); + assert "áéíóúñ".equals(tokens.get(0)); + assert "éééé".equals(tokens.get(1)); } }; diff --git a/org.argeo.util/ext/test/org/argeo/util/CsvParserParseFileTest.java b/org.argeo.util/ext/test/org/argeo/util/CsvParserParseFileTest.java index a937ee7c7..0ddc26842 100644 --- a/org.argeo.util/ext/test/org/argeo/util/CsvParserParseFileTest.java +++ b/org.argeo.util/ext/test/org/argeo/util/CsvParserParseFileTest.java @@ -19,17 +19,14 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; -import junit.framework.TestCase; - -public class CsvParserParseFileTest extends TestCase { +/** Test that {@link CsvParser} can properly parse a CSV file. */ +public class CsvParserParseFileTest { public void testParse() throws Exception { final Map> lines = new HashMap>(); - InputStream in = getClass().getResourceAsStream( - "/org/argeo/util/ReferenceFile.csv"); + InputStream in = getClass().getResourceAsStream("/org/argeo/util/ReferenceFile.csv"); CsvParserWithLinesAsMap parser = new CsvParserWithLinesAsMap() { - protected void processLine(Integer lineNumber, - Map line) { + protected void processLine(Integer lineNumber, Map line) { lines.put(lineNumber, line); } }; @@ -37,7 +34,7 @@ public class CsvParserParseFileTest extends TestCase { parser.parse(in); in.close(); - assertEquals(5, lines.size()); + assert 5 == lines.size(); } } diff --git a/org.argeo.util/ext/test/org/argeo/util/CsvParserTestCase.java b/org.argeo.util/ext/test/org/argeo/util/CsvParserTest.java similarity index 67% rename from org.argeo.util/ext/test/org/argeo/util/CsvParserTestCase.java rename to org.argeo.util/ext/test/org/argeo/util/CsvParserTest.java index 02e8d1b59..e1b6877f4 100644 --- a/org.argeo.util/ext/test/org/argeo/util/CsvParserTestCase.java +++ b/org.argeo.util/ext/test/org/argeo/util/CsvParserTest.java @@ -19,26 +19,22 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; -import junit.framework.TestCase; - -public class CsvParserTestCase extends TestCase { +/** {@link CsvParser} tests. */ +public class CsvParserTest { public void testParse() throws Exception { - String toParse = "Header1,\"Header\n2\",Header3,\"Header4\"\n" - + "Col1,\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n" - + "Col1,\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n" - + "Col1,\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n"; + String toParse = "Header1,\"Header\n2\",Header3,\"Header4\"\n" + "Col1,\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n" + + "Col1,\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n" + "Col1,\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n"; InputStream in = new ByteArrayInputStream(toParse.getBytes()); CsvParser csvParser = new CsvParser() { - protected void processLine(Integer lineNumber, List header, - List tokens) { - assertEquals(header.size(), tokens.size()); - assertEquals(4, tokens.size()); - assertEquals("Col1", tokens.get(0)); - assertEquals("Col\n2", tokens.get(1)); - assertEquals("Col3", tokens.get(2)); - assertEquals("\"Col4\"", tokens.get(3)); + protected void processLine(Integer lineNumber, List header, List tokens) { + assert header.size() == tokens.size(); + assert 4 == tokens.size(); + assert "Col1".equals(tokens.get(0)); + assert "Col\n2".equals(tokens.get(1)); + assert "Col3".equals(tokens.get(2)); + assert "\"Col4\"".equals(tokens.get(3)); } }; diff --git a/org.argeo.util/ext/test/org/argeo/util/CsvParserWithQuotedSeparatorTest.java b/org.argeo.util/ext/test/org/argeo/util/CsvParserWithQuotedSeparatorTest.java index d4131a046..f4095bb72 100644 --- a/org.argeo.util/ext/test/org/argeo/util/CsvParserWithQuotedSeparatorTest.java +++ b/org.argeo.util/ext/test/org/argeo/util/CsvParserWithQuotedSeparatorTest.java @@ -21,9 +21,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.TestCase; - -public class CsvParserWithQuotedSeparatorTest extends TestCase { +/** Test that {@link CsvParser} deals properly with "" quotes. */ +public class CsvParserWithQuotedSeparatorTest { public void testSimpleParse() throws Exception { String toParse = "Header1,\"Header2\",Header3,\"Header4\"\n" + "\"Col1, Col2\",\"Col\n2\",Col3,\"\"\"Col4\"\"\"\n"; @@ -31,11 +30,10 @@ public class CsvParserWithQuotedSeparatorTest extends TestCase { InputStream in = new ByteArrayInputStream(toParse.getBytes()); CsvParser csvParser = new CsvParser() { - protected void processLine(Integer lineNumber, List header, - List tokens) { - assertEquals(header.size(), tokens.size()); - assertEquals(4, tokens.size()); - assertEquals("Col1, Col2", tokens.get(0)); + protected void processLine(Integer lineNumber, List header, List tokens) { + assert header.size() == tokens.size(); + assert 4 == tokens.size(); + assert "Col1, Col2".equals(tokens.get(0)); } }; // System.out.println(toParse); @@ -47,12 +45,10 @@ public class CsvParserWithQuotedSeparatorTest extends TestCase { public void testParseFile() throws Exception { final Map> lines = new HashMap>(); - InputStream in = getClass().getResourceAsStream( - "/org/argeo/util/ReferenceFile.csv"); + InputStream in = getClass().getResourceAsStream("/org/argeo/util/ReferenceFile.csv"); CsvParserWithLinesAsMap parser = new CsvParserWithLinesAsMap() { - protected void processLine(Integer lineNumber, - Map line) { + protected void processLine(Integer lineNumber, Map line) { // System.out.println("processing line #" + lineNumber); lines.put(lineNumber, line); } @@ -62,17 +58,16 @@ public class CsvParserWithQuotedSeparatorTest extends TestCase { in.close(); Map line = lines.get(2); - assertEquals(",,,,", line.get("Coma testing")); + assert ",,,,".equals(line.get("Coma testing")); line = lines.get(3); - assertEquals(",, ,,", line.get("Coma testing")); + assert ",, ,,".equals(line.get("Coma testing")); line = lines.get(4); - assertEquals("module1, module2", line.get("Coma testing")); + assert "module1, module2".equals(line.get("Coma testing")); line = lines.get(5); - assertEquals("module1,module2", line.get("Coma testing")); + assert "module1,module2".equals(line.get("Coma testing")); line = lines.get(6); - assertEquals(",module1,module2, \nmodule3, module4", - line.get("Coma testing")); - assertEquals(5, lines.size()); + assert ",module1,module2, \nmodule3, module4".equals(line.get("Coma testing")); + assert 5 == lines.size(); } } diff --git a/org.argeo.util/ext/test/org/argeo/util/CsvWriterTestCase.java b/org.argeo.util/ext/test/org/argeo/util/CsvWriterTest.java similarity index 86% rename from org.argeo.util/ext/test/org/argeo/util/CsvWriterTestCase.java rename to org.argeo.util/ext/test/org/argeo/util/CsvWriterTest.java index 26b356def..fcd2d606b 100644 --- a/org.argeo.util/ext/test/org/argeo/util/CsvWriterTestCase.java +++ b/org.argeo.util/ext/test/org/argeo/util/CsvWriterTest.java @@ -21,31 +21,27 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; - -public class CsvWriterTestCase extends TestCase { +/** {@link CsvWriter} tests. */ +public class CsvWriterTest { public void testWrite() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); final CsvWriter csvWriter = new CsvWriter(out); - String[] header = { "Header1", "Header 2", "Header,3", "Header\n4", - "Header\"5\"" }; - String[] line1 = { "Value1", "Value 2", "Value,3", "Value\n4", - "Value\"5\"" }; + String[] header = { "Header1", "Header 2", "Header,3", "Header\n4", "Header\"5\"" }; + String[] line1 = { "Value1", "Value 2", "Value,3", "Value\n4", "Value\"5\"" }; csvWriter.writeLine(Arrays.asList(header)); csvWriter.writeLine(Arrays.asList(line1)); String reference = "Header1,Header 2,\"Header,3\",\"Header\n4\",\"Header\"\"5\"\"\"\n" + "Value1,Value 2,\"Value,3\",\"Value\n4\",\"Value\"\"5\"\"\"\n"; String written = new String(out.toByteArray()); - assertEquals(reference, written); + assert reference.equals(written); out.close(); System.out.println(written); final List allTokens = new ArrayList(); CsvParser csvParser = new CsvParser() { - protected void processLine(Integer lineNumber, List header, - List tokens) { + protected void processLine(Integer lineNumber, List header, List tokens) { if (lineNumber == 2) allTokens.addAll(header); allTokens.addAll(tokens); @@ -58,9 +54,9 @@ public class CsvWriterTestCase extends TestCase { allTokensRef.addAll(Arrays.asList(header)); allTokensRef.addAll(Arrays.asList(line1)); - assertEquals(allTokensRef.size(), allTokens.size()); + assert allTokensRef.size() == allTokens.size(); for (int i = 0; i < allTokensRef.size(); i++) - assertEquals(allTokensRef.get(i), allTokens.get(i)); + assert allTokensRef.get(i).equals(allTokens.get(i)); } } diff --git a/org.argeo.util/src/org/argeo/util/test/Test.java b/org.argeo.util/src/org/argeo/util/test/Tester.java similarity index 52% rename from org.argeo.util/src/org/argeo/util/test/Test.java rename to org.argeo.util/src/org/argeo/util/test/Tester.java index 74f165ef2..36e27de72 100644 --- a/org.argeo.util/src/org/argeo/util/test/Test.java +++ b/org.argeo.util/src/org/argeo/util/test/Tester.java @@ -8,35 +8,68 @@ import java.util.Map; import java.util.TreeMap; /** A generic tester based on Java assertions and functional programming. */ -public class Test { - private Map results = Collections.synchronizedSortedMap(new TreeMap<>()); - - protected void execute(String className) throws Throwable { - ClassLoader classLoader = Test.class.getClassLoader(); - Class clss = classLoader.loadClass(className); - boolean assertionsEnabled = clss.desiredAssertionStatus(); - if (!assertionsEnabled) - throw new IllegalStateException("Test runner " + getClass().getName() - + " requires Java assertions to be enabled. Call the JVM with the -ea argument."); - Object obj = clss.getDeclaredConstructor().newInstance(); +public class Tester { + private Map results = Collections.synchronizedSortedMap(new TreeMap<>()); + + private ClassLoader classLoader; + + /** Use {@link Thread#getContextClassLoader()} by default. */ + public Tester() { + this(Thread.currentThread().getContextClassLoader()); + } + + public Tester(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public void execute(String className) { + Class clss; + try { + clss = classLoader.loadClass(className); + boolean assertionsEnabled = clss.desiredAssertionStatus(); + if (!assertionsEnabled) + throw new IllegalStateException("Test runner " + getClass().getName() + + " requires Java assertions to be enabled. Call the JVM with the -ea argument."); + } catch (Exception e1) { + throw new IllegalArgumentException("Cannot initalise test for " + className, e1); + + } List methods = findMethods(clss); if (methods.size() == 0) throw new IllegalArgumentException("No test method found in " + clss); // TODO make order more predictable? for (Method method : methods) { String uid = method.getDeclaringClass().getName() + "#" + method.getName(); - TestStatus testStatus = new TestStatus(uid); + TesterStatus testStatus = new TesterStatus(uid); + Object obj = null; try { + beforeTest(uid, method); + obj = clss.getDeclaredConstructor().newInstance(); method.invoke(obj); testStatus.setPassed(); + afterTestPassed(uid, method, obj); } catch (Exception e) { testStatus.setFailed(e); + afterTestFailed(uid, method, obj, e); } finally { results.put(uid, testStatus); } } } + protected void beforeTest(String uid, Method method) { + // System.out.println(uid + ": STARTING"); + } + + protected void afterTestPassed(String uid, Method method, Object obj) { + System.out.println(uid + ": PASSED"); + } + + protected void afterTestFailed(String uid, Method method, Object obj, Throwable e) { + System.out.println(uid + ": FAILED"); + e.printStackTrace(); + } + protected List findMethods(Class clss) { List methods = new ArrayList(); // Method call = getMethod(clss, "call"); @@ -72,22 +105,22 @@ public class Test { className = args[0]; } - Test test = new Test(); + Tester test = new Tester(); try { test.execute(className); } catch (Throwable e) { e.printStackTrace(); } - Map r = test.results; + Map r = test.results; for (String uid : r.keySet()) { - TestStatus testStatus = r.get(uid); + TesterStatus testStatus = r.get(uid); System.out.println(testStatus); } } public static String usage() { - return "java " + Test.class.getName() + " [test class name]"; + return "java " + Tester.class.getName() + " [test class name]"; } } diff --git a/org.argeo.util/src/org/argeo/util/test/TestStatus.java b/org.argeo.util/src/org/argeo/util/test/TesterStatus.java similarity index 89% rename from org.argeo.util/src/org/argeo/util/test/TestStatus.java rename to org.argeo.util/src/org/argeo/util/test/TesterStatus.java index 79cfbcdd3..d533e9457 100644 --- a/org.argeo.util/src/org/argeo/util/test/TestStatus.java +++ b/org.argeo.util/src/org/argeo/util/test/TesterStatus.java @@ -3,19 +3,19 @@ package org.argeo.util.test; import java.io.Serializable; /** The status of a test. */ -public class TestStatus implements Serializable { +public class TesterStatus implements Serializable { private static final long serialVersionUID = 6272975746885487000L; private Boolean passed = null; private final String uid; private Throwable throwable = null; - public TestStatus(String uid) { + public TesterStatus(String uid) { this.uid = uid; } /** For cloning. */ - public TestStatus(String uid, Boolean passed, Throwable throwable) { + public TesterStatus(String uid, Boolean passed, Throwable throwable) { this(uid); this.passed = passed; this.throwable = throwable; @@ -76,8 +76,8 @@ public class TestStatus implements Serializable { @Override public boolean equals(Object o) { - if (o instanceof TestStatus) { - TestStatus other = (TestStatus) o; + if (o instanceof TesterStatus) { + TesterStatus other = (TesterStatus) o; // we don't check consistency for performance purposes // this equals() is supposed to be used in collections or for transfer return other.uid.equals(uid); -- 2.30.2