/*************************GO-LICENSE-START********************************* * Copyright 2014 ThoughtWorks, Inc. * * 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. *************************GO-LICENSE-END***********************************/ package com.thoughtworks.go.plugin.infra.plugininfo; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.UUID; import com.thoughtworks.go.util.FileUtil; import org.apache.commons.io.FileUtils; import org.hamcrest.CoreMatchers; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; public class GoPluginDescriptorBuilderTest { private static final File TMP_DIR = new File("./tmp"); private static final String TESTPLUGIN_ID = "testplugin.descriptorValidator"; private GoPluginDescriptorBuilder goPluginDescriptorBuilder; private File pluginDirectory; private File bundleDirectory; @Before public void setUp() throws Exception { pluginDirectory = new File(TMP_DIR + "-plugins-" + UUID.randomUUID().toString()); FileUtil.recreateDirectory(pluginDirectory); bundleDirectory = new File(TMP_DIR + "-bundles-" + UUID.randomUUID().toString()); FileUtil.recreateDirectory(bundleDirectory); goPluginDescriptorBuilder = spy(new GoPluginDescriptorBuilder()); doReturn(bundleDirectory).when(goPluginDescriptorBuilder).bundlePath(); } @After public void tearDown() throws Exception { FileUtils.deleteQuietly(pluginDirectory); FileUtils.deleteQuietly(bundleDirectory); } @Test public void shouldCreateThePluginDescriptorFromGivenPluginJarWithPluginXML() throws Exception { String pluginJarName = "descriptor-aware-test-plugin.jar"; copyPluginToThePluginDirectory(pluginDirectory, pluginJarName); File pluginJarFile = new File(pluginDirectory, pluginJarName); GoPluginDescriptor descriptor = goPluginDescriptorBuilder.build(pluginJarFile, true); GoPluginDescriptor expectedDescriptor = buildExpectedDescriptor (pluginJarName, pluginJarFile.getAbsolutePath()); assertThat(descriptor, CoreMatchers.is(expectedDescriptor)); assertThat(descriptor.isInvalid(), CoreMatchers.is(false)); assertThat(descriptor.isBundledPlugin(), CoreMatchers.is(true)); } @Test public void shouldCreateInvalidPluginDescriptorBecausePluginXMLDoesNotConformToXSD() throws Exception { String pluginJarName = "invalid-descriptor-plugin.jar"; copyPluginToThePluginDirectory(pluginDirectory, pluginJarName); File pluginJarFile = new File(pluginDirectory, pluginJarName); GoPluginDescriptor descriptor = goPluginDescriptorBuilder.build(pluginJarFile, true); GoPluginDescriptor expectedDescriptor = buildXMLSchemaErrorDescriptor(pluginJarName); assertThat(descriptor, CoreMatchers.is(expectedDescriptor)); assertThat(descriptor.isInvalid(), CoreMatchers.is(true)); assertThat(descriptor.isBundledPlugin(), CoreMatchers.is(true)); assertThat(descriptor.getStatus().getMessages(), is(expectedDescriptor.getStatus().getMessages())); } @Test public void shouldCreatePluginDescriptorEvenIfPluginXMLIsNotFound() throws Exception { String pluginJarName = "descriptor-aware-test-plugin-with-no-plugin-xml.jar"; copyPluginToThePluginDirectory(pluginDirectory, pluginJarName); File pluginJarFile = new File(pluginDirectory, pluginJarName); GoPluginDescriptor descriptor = goPluginDescriptorBuilder.build(pluginJarFile, false); assertThat(descriptor.isInvalid(), is(false)); assertThat(descriptor.id(), is(pluginJarName)); } @Test(expected = RuntimeException.class) public void shouldThrowExceptionForInvalidPluginIfThePluginJarDoesNotExist() throws Exception { goPluginDescriptorBuilder.build(new File(pluginDirectory, "invalid"), true); } private void copyPluginToThePluginDirectory(File pluginDir, String destinationFilenameOfPlugin) throws IOException, URISyntaxException { URL resource = getClass().getClassLoader().getResource("defaultFiles/" + destinationFilenameOfPlugin); FileUtils.copyURLToFile(resource, new File(pluginDir, destinationFilenameOfPlugin)); } private GoPluginDescriptor buildExpectedDescriptor(String name, String pluginJarFileLocation) { /* <?xml version="1.0" encoding="utf-8" ?> <go-plugin id="testplugin.descriptorValidator" version="1"> <about> <name>Plugin Descriptor Validator</name> <version>1.0.1</version> <target-go-version>12.4</target-go-version> <description>Validates its own plugin descriptor</description> <vendor> <name>ThoughtWorks Go Team</name> <url>www.thoughtworks.com</url> </vendor> <target-os> <value>Linux</value> <value>Windows</value> </target-os> </about> </go-plugin> */ return new GoPluginDescriptor(TESTPLUGIN_ID, "1", new GoPluginDescriptor.About("Plugin Descriptor Validator", "1.0.1", "12.4", "Validates its own plugin descriptor", new GoPluginDescriptor.Vendor("ThoughtWorks Go Team", "www.thoughtworks.com"), Arrays.asList("Linux", "Windows", "Mac OS X")), pluginJarFileLocation, new File(bundleDirectory, name), true); } private GoPluginDescriptor buildXMLSchemaErrorDescriptor(String name) { /* <?xml version="1.0" encoding="utf-8" ?> <go-plugin id="testplugin.descriptorValidator" version="1"> <about> <name>Plugin Descriptor Validator</name> <version>1.0.1</version> <target-go-version>12.4</target-go-version> <description>Validates its own plugin descriptor</description> <vendor> <name>ThoughtWorks Go Team</name> <url>www.thoughtworks.com</url> </vendor> <target-os> <value>Linux</value> <value>Windows</value> </target-os> <target-os> // this tag is repeated - this is invalid <value>Linux</value> <value>Windows</value> </target-os> </about> </go-plugin> */ File pluginJarFile = new File(pluginDirectory, name); return GoPluginDescriptor.usingId(pluginJarFile.getName(), pluginJarFile.getAbsolutePath(), new File(bundleDirectory, name), true) .markAsInvalid(Arrays.asList(String.format("Plugin with ID (%s) is not valid: %s.", pluginJarFile.getName(), "XML Schema validation of Plugin Descriptor(plugin.xml) failed. Cause: cvc-complex-type.2.4.d: Invalid content was found starting with element 'target-os'. No child element is expected at this point") ), null); } }