| /* |
| * 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.geode.internal; |
| |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.assertj.core.api.Assertions.assertThatThrownBy; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| import org.apache.commons.io.IOUtils; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| |
| import org.apache.geode.test.compiler.ClassBuilder; |
| |
| public class JarDeployerIntegrationTest { |
| private ClassBuilder classBuilder; |
| |
| @Rule |
| public TemporaryFolder temporaryFolder = new TemporaryFolder(); |
| |
| JarDeployer jarDeployer; |
| |
| @Before |
| public void setup() { |
| classBuilder = new ClassBuilder(); |
| jarDeployer = new JarDeployer(temporaryFolder.getRoot()); |
| } |
| |
| private byte[] createJarWithClass(String className) throws IOException { |
| String stringBuilder = "package integration.parent;" + "public class " + className + " {}"; |
| |
| return this.classBuilder.createJarFromClassContent("integration/parent/" + className, |
| stringBuilder); |
| } |
| |
| @Test |
| public void testFileVersioning() throws Exception { |
| String jarName = "JarDeployerIntegrationTest.jar"; |
| |
| byte[] firstJarBytes = createJarWithClass("ClassA"); |
| File jarFile1 = writeJarBytes(firstJarBytes); |
| |
| // First deploy of the JAR file |
| DeployedJar firstDeployedJar = jarDeployer.deployWithoutRegistering(jarName, jarFile1); |
| |
| assertThat(firstDeployedJar.getFile()).exists().hasBinaryContent(firstJarBytes); |
| assertThat(firstDeployedJar.getFile().getName()).contains(".v1.").doesNotContain(".v2."); |
| |
| // Now deploy an updated JAR file and make sure that the next version of the JAR file |
| // was created |
| byte[] secondJarBytes = createJarWithClass("ClassB"); |
| File jarFile2 = writeJarBytes(secondJarBytes); |
| |
| DeployedJar secondDeployedJar = jarDeployer.deployWithoutRegistering(jarName, jarFile2); |
| File secondDeployedJarFile = new File(secondDeployedJar.getFileCanonicalPath()); |
| |
| assertThat(secondDeployedJarFile).exists().hasBinaryContent(secondJarBytes); |
| assertThat(secondDeployedJarFile.getName()).contains(".v2.").doesNotContain(".v1."); |
| |
| File[] sortedOldJars = jarDeployer.findSortedOldVersionsOfJar(jarName); |
| assertThat(sortedOldJars).hasSize(2); |
| assertThat(sortedOldJars[0].getName()).contains(".v2."); |
| assertThat(sortedOldJars[1].getName()).contains(".v1."); |
| assertThat(jarDeployer.findDistinctDeployedJarsOnDisk()).hasSize(1); |
| } |
| |
| @Test |
| public void testDeployToInvalidDirectory() throws Exception { |
| final File alternateDir = new File(temporaryFolder.getRoot(), "JarDeployerDUnit"); |
| alternateDir.delete(); |
| |
| final JarDeployer jarDeployer = new JarDeployer(alternateDir); |
| final byte[] jarBytes = this.classBuilder.createJarFromName("JarDeployerDUnitDTID"); |
| File jarFile = writeJarBytes(jarBytes); |
| |
| // Test to verify that deployment fails if the directory doesn't exist. |
| assertThatThrownBy(() -> { |
| jarDeployer.deployWithoutRegistering("JarDeployerIntegrationTest.jar", jarFile); |
| }).isInstanceOf(IOException.class).hasMessageContaining("Unable to write to deploy directory:"); |
| } |
| |
| @Test |
| public void testVersionNumberCreation() throws Exception { |
| File versionedName = jarDeployer.getNextVersionedJarFile("myJar.jar"); |
| assertThat(versionedName.getName()).isEqualTo("myJar.v1.jar"); |
| |
| byte[] jarBytes = this.classBuilder.createJarFromName("ClassA"); |
| File jarFile = writeJarBytes(jarBytes); |
| File deployedJarFile = jarDeployer.deployWithoutRegistering("myJar.jar", jarFile).getFile(); |
| |
| assertThat(deployedJarFile.getName()).isEqualTo("myJar.v1.jar"); |
| |
| File secondDeployedJarFile = |
| jarDeployer.deployWithoutRegistering("myJar.jar", deployedJarFile).getFile(); |
| |
| assertThat(secondDeployedJarFile.getName()).isEqualTo("myJar.v2.jar"); |
| } |
| |
| @Test |
| public void testVersionNumberMatcher() throws IOException { |
| int version = |
| JarDeployer.extractVersionFromFilename(temporaryFolder.newFile("MyJar.v1.jar").getName()); |
| |
| assertThat(version).isEqualTo(1); |
| } |
| |
| @Test |
| public void testRenamingOfOldJarFiles() throws Exception { |
| File deployDir = jarDeployer.getDeployDirectory(); |
| |
| File jarAVersion1 = new File(deployDir, "vf.gf#myJarA.jar#1"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion1); |
| |
| File jarAVersion2 = new File(deployDir, "vf.gf#myJarA.jar#2"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion2); |
| |
| File jarBVersion2 = new File(deployDir, "vf.gf#myJarB.jar#2"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion2); |
| |
| File jarBVersion3 = new File(deployDir, "vf.gf#myJarB.jar#3"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion3); |
| |
| Set<File> deployedJarsBeforeRename = Stream |
| .of(jarAVersion1, jarAVersion2, jarBVersion2, jarBVersion3).collect(Collectors.toSet()); |
| |
| jarDeployer.renameJarsWithOldNamingConvention(); |
| |
| deployedJarsBeforeRename.forEach(oldJar -> assertThat(oldJar).doesNotExist()); |
| |
| File renamedJarAVersion1 = new File(deployDir, "myJarA.v1.jar"); |
| File renamedJarAVersion2 = new File(deployDir, "myJarA.v2.jar"); |
| File renamedJarBVersion2 = new File(deployDir, "myJarB.v2.jar"); |
| File renamedJarBVersion3 = new File(deployDir, "myJarB.v3.jar"); |
| Set<File> expectedJarsAfterRename = Stream |
| .of(renamedJarAVersion1, renamedJarAVersion2, renamedJarBVersion2, renamedJarBVersion3) |
| .collect(Collectors.toSet()); |
| |
| Set<File> actualJarsInDeployDir = |
| Stream.of(jarDeployer.getDeployDirectory().listFiles()).collect(Collectors.toSet()); |
| |
| assertThat(actualJarsInDeployDir).isEqualTo(expectedJarsAfterRename); |
| } |
| |
| @Test |
| public void testOldJarNameMatcher() throws Exception { |
| File deployDir = jarDeployer.getDeployDirectory(); |
| |
| File jarAVersion1 = new File(deployDir, "vf.gf#myJarA.jar#1"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion1); |
| |
| File jarAVersion2 = new File(deployDir, "vf.gf#myJarA.jar#2"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion2); |
| |
| File jarBVersion2 = new File(deployDir, "vf.gf#myJarB.jar#2"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion2); |
| |
| File jarBVersion3 = new File(deployDir, "vf.gf#myJarB.jar#3"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion3); |
| |
| Set<File> jarsWithOldNamingConvention = Stream |
| .of(jarAVersion1, jarAVersion2, jarBVersion2, jarBVersion3).collect(Collectors.toSet()); |
| |
| jarsWithOldNamingConvention.forEach( |
| jarFile -> assertThat(jarDeployer.isOldNamingConvention(jarFile.getName())).isTrue()); |
| |
| Set<File> foundJarsWithOldNamingConvention = jarDeployer.findJarsWithOldNamingConvention(); |
| assertThat(foundJarsWithOldNamingConvention).isEqualTo(jarsWithOldNamingConvention); |
| } |
| |
| |
| @Test |
| public void testDeleteAllVersionsOfJar() throws Exception { |
| File deployDir = jarDeployer.getDeployDirectory(); |
| |
| File jarAVersion1 = new File(deployDir, "myJarA.v1.jar"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion1); |
| |
| File jarAVersion2 = new File(deployDir, "myJarA.v2.jar"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion2); |
| |
| File jarBVersion2 = new File(deployDir, "myJarB.v2.jar"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion2); |
| |
| File jarBVersion3 = new File(deployDir, "myJarB.v3.jar"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion3); |
| |
| jarDeployer.deleteAllVersionsOfJar("myJarA.jar"); |
| |
| assertThat(jarAVersion1).doesNotExist(); |
| assertThat(jarAVersion2).doesNotExist(); |
| assertThat(jarBVersion2).exists(); |
| assertThat(jarBVersion3).exists(); |
| } |
| |
| |
| @Test |
| public void testDeleteOtherVersionsOfJar() throws Exception { |
| File deployDir = jarDeployer.getDeployDirectory(); |
| |
| File jarAVersion1 = new File(deployDir, "myJarA.v1.jar"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion1); |
| |
| File jarAVersion2 = new File(deployDir, "myJarA.v2.jar"); |
| this.classBuilder.writeJarFromName("ClassA", jarAVersion2); |
| |
| File jarBVersion2 = new File(deployDir, "myJarB.v2.jar"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion2); |
| |
| File jarBVersion3 = new File(deployDir, "myJarB.v3.jar"); |
| this.classBuilder.writeJarFromName("ClassB", jarBVersion3); |
| |
| DeployedJar deployedJarBVersion3 = new DeployedJar(jarBVersion3, "myJarB.jar"); |
| jarDeployer.deleteOtherVersionsOfJar(deployedJarBVersion3); |
| |
| assertThat(jarAVersion1).exists(); |
| assertThat(jarAVersion2).exists(); |
| assertThat(jarBVersion2).doesNotExist(); |
| assertThat(jarBVersion3).exists(); |
| |
| DeployedJar deployedJarAVersion1 = new DeployedJar(jarAVersion1, "myJarA.jar"); |
| jarDeployer.deleteOtherVersionsOfJar(deployedJarAVersion1); |
| |
| assertThat(jarAVersion1).exists(); |
| assertThat(jarAVersion2).doesNotExist(); |
| assertThat(jarBVersion2).doesNotExist(); |
| assertThat(jarBVersion3).exists(); |
| } |
| |
| private File writeJarBytes(byte[] content) throws IOException { |
| File tempJar = temporaryFolder.newFile(); |
| IOUtils.copy(new ByteArrayInputStream(content), new FileOutputStream(tempJar)); |
| return tempJar; |
| } |
| |
| } |