BootstrapDeployersTest enhancements and AssembledDirectory
adrian.brock Jul 17, 2008 10:47 AMI've added some support to the BootstrapDeployersTest
so you can use the vfs's AssembledDirectory.
i.e. you can create deployments out of disparate parts of the testsuite structure
For some simple examples see:
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/classloader/test/BootstrapDeployersSmokeTestUnitTestCase.java?revision=75958&view=markup
But this was a lot harder work than I expected. The AssembledDirectory
has a number of problems (bugs?) and is not very easy to use.
There's some FIXMEs here:
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/BootstrapDeployersTest.java?revision=75958&view=markup
which show where the problems are, but I'll give some more explanation on this thread
First the only factory for AssembledDirectory is the AssembledContext
which is not a part of the public api.
Also the api should return an AssembledDirectory so you don't have
to cast from the super class.
import org.jboss.virtual.plugins.context.vfs.AssembledContext; ... // FIXME Missing factor method in the public api protected AssembledDirectory createAssembledDirectory(String name) throws Exception { AssembledContext ctx = new AssembledContext(name, ""); return (AssembledDirectory) ctx.getRoot().getVirtualFile(); }
There is no support for doing something as simple as adding a META-INF directory
and all its contents to the assembled directory, so I wrote it myself,
but this obviously should be in the AssembledDirectory class.
// FIXME why doesn't AssembledDirectory support this simple use case? protected void addPath(final AssembledDirectory dir, String path, String name) throws Exception { URL url = getResource(path); if (url == null) fail(path + " not found"); VirtualFile file = VFS.getVirtualFile(url, name); final VisitorAttributes va = new VisitorAttributes(); va.setLeavesOnly(true); SuffixesExcludeFilter noJars = new SuffixesExcludeFilter(JarUtils.getSuffixes()); va.setRecurseFilter(noJars); VirtualFileVisitor visitor = new VirtualFileVisitor() { public VisitorAttributes getAttributes() { return va; } public void visit(VirtualFile virtualFile) { dir.mkdirs(virtualFile.getPathName()).addChild(virtualFile); } }; file.visit(visitor); }
The urls for assembled directories are broken.
e.g. if you have vfs://a/ and do mkdir("b") on it, you get back a url
that says vfs://ab/
I think this is because it passes null to the "path" when it constructs
the URI in AssembledContext, but I didn't confirm it.
For now I've hacked the url handling in the test.
protected DeploymentUnit assertChild(DeploymentUnit parent, String name) { // FIXME AssembledContext URLs are broken String parentName = parent.getName(); if (parentName.endsWith("/")) parentName = parentName.substring(0, parentName.length()-1); name = name + "/"; name = parentName + name ; List<DeploymentUnit> children = parent.getChildren(); for (DeploymentUnit child : children) { if (name.equals(child.getName())) return child; } throw new AssertionFailedError("Child " + name + " not found in " + children); }
addResources() is a not very easy to use api and it is slow
(takes about 1 second for deployers-vfs).
The example here looks easy, but it actually scans the whole class
and resource structure, even though I've already told it
which package I want it to add.
Having filters is nice, but there's no need to be dumb or slow about simple cases.
protected void addPackage(AssembledDirectory dir, Class<?> reference) throws Exception { String packagePath = ClassLoaderUtils.packageNameToPath(reference.getName()); dir.addResources(reference, new String[] { packagePath + "/*.class" } , new String[0]); }
Part of the reason it is slow is that it is trying to open jars
(some of which in deployers-vfs are deliberately broken to test
error handling).
I hacked the test to reduce the noise from this,
as the FIXME says, there should really be a method in AbstractTestCase
to change the logging level, rather than having to assume log4j
protected void setUp() throws Exception { super.setUp(); // This is a hack for a hack. ;-) AbstractJDKChecker.getExcluded().add(BootstrapDeployersTest.class); // Reduce the noise from the VFS // FIXME add method change logging levels to AbstractTestCase Logger.getLogger(FileSystemContext.class).setLevel(Level.INFO); }