/** * 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.ambari.server.view; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import javax.xml.bind.JAXBException; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.orm.dao.ViewDAO; import org.apache.ambari.server.orm.entities.ResourceTypeEntity; import org.apache.ambari.server.orm.entities.ViewEntity; import org.apache.ambari.server.orm.entities.ViewEntityTest; import org.apache.ambari.server.view.configuration.ViewConfig; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * ViewExtractor tests. */ public class ViewExtractorTest { private static final File extractedArchiveDir = createNiceMock(File.class); private static final File viewArchive = createNiceMock(File.class); private static final File archiveDir = createNiceMock(File.class); private static final File entryFile = createNiceMock(File.class); private static final File classesDir = createNiceMock(File.class); private static final File libDir = createNiceMock(File.class); private static final File metaInfDir = createNiceMock(File.class); private static final JarInputStream viewJarFile = createNiceMock(JarInputStream.class); private static final JarEntry jarEntry = createNiceMock(JarEntry.class); private static final FileOutputStream fos = createMock(FileOutputStream.class); private static final Configuration configuration = createNiceMock(Configuration.class); private static final File viewDir = createNiceMock(File.class); private static final File fileEntry = createNiceMock(File.class); private static final ViewDAO viewDAO = createMock(ViewDAO.class); @Before public void resetGlobalMocks() { reset(extractedArchiveDir, viewArchive,archiveDir,entryFile, classesDir, libDir, metaInfDir, viewJarFile, jarEntry, fos, configuration, viewDir, fileEntry, viewDAO); } @Test public void testExtractViewArchive() throws Exception { ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity(); resourceTypeEntity.setId(10); resourceTypeEntity.setName("MY_VIEW{1.0.0}"); ViewEntity viewDefinition = ViewEntityTest.getViewEntity(); viewDefinition.setResourceType(resourceTypeEntity); // set expectations expect(configuration.getViewExtractionThreadPoolCoreSize()).andReturn(2).anyTimes(); expect(configuration.getViewExtractionThreadPoolMaxSize()).andReturn(3).anyTimes(); expect(configuration.getViewExtractionThreadPoolTimeout()).andReturn(10000L).anyTimes(); if (System.getProperty("os.name").contains("Windows")) { expect(viewArchive.getAbsolutePath()).andReturn("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}").anyTimes(); } else { expect(viewArchive.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}").anyTimes(); } expect(archiveDir.exists()).andReturn(false); if (System.getProperty("os.name").contains("Windows")) { expect(archiveDir.getAbsolutePath()).andReturn("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}").anyTimes(); } else { expect(archiveDir.getAbsolutePath()).andReturn("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}").anyTimes(); } expect(archiveDir.mkdir()).andReturn(true); expect(archiveDir.toURI()).andReturn(new URI("file:./")); expect(metaInfDir.mkdir()).andReturn(true); expect(viewJarFile.getNextJarEntry()).andReturn(jarEntry); expect(viewJarFile.getNextJarEntry()).andReturn(null); expect(jarEntry.getName()).andReturn("view.xml"); expect(viewJarFile.read(anyObject(byte[].class))).andReturn(10); expect(viewJarFile.read(anyObject(byte[].class))).andReturn(-1); fos.write(anyObject(byte[].class), eq(0), eq(10)); fos.flush(); fos.close(); viewJarFile.closeEntry(); viewJarFile.close(); expect(classesDir.exists()).andReturn(true); expect(classesDir.toURI()).andReturn(new URI("file:./")); expect(libDir.exists()).andReturn(true); expect(libDir.listFiles()).andReturn(new File[]{fileEntry}); expect(fileEntry.toURI()).andReturn(new URI("file:./")); replay(extractedArchiveDir, viewArchive, archiveDir, entryFile, classesDir, libDir, metaInfDir, viewJarFile, jarEntry, fos, configuration, viewDir, fileEntry, viewDAO); ViewExtractor viewExtractor = getViewExtractor(viewDefinition); viewExtractor.extractViewArchive(viewDefinition, viewArchive, archiveDir); verify(extractedArchiveDir, viewArchive, archiveDir, entryFile, classesDir, libDir, metaInfDir, viewJarFile, jarEntry, fos, configuration, viewDir, fileEntry, viewDAO); } @Test public void testEnsureExtractedArchiveDirectory() throws Exception { ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity(); resourceTypeEntity.setId(10); resourceTypeEntity.setName("MY_VIEW{1.0.0}"); ViewEntity viewDefinition = ViewEntityTest.getViewEntity(); viewDefinition.setResourceType(resourceTypeEntity); expect(extractedArchiveDir.exists()).andReturn(true); replay(extractedArchiveDir, viewArchive, archiveDir, entryFile, classesDir, libDir, metaInfDir, viewJarFile, jarEntry, fos, configuration, viewDir, fileEntry, viewDAO); ViewExtractor viewExtractor = getViewExtractor(viewDefinition); if (System.getProperty("os.name").contains("Windows")) { Assert.assertTrue(viewExtractor.ensureExtractedArchiveDirectory("\\var\\lib\\ambari-server\\resources\\views\\work")); } else { Assert.assertTrue(viewExtractor.ensureExtractedArchiveDirectory("/var/lib/ambari-server/resources/views/work")); } verify(extractedArchiveDir, viewArchive, archiveDir, entryFile, classesDir, libDir, metaInfDir, viewJarFile, jarEntry, fos, configuration, viewDir, fileEntry, viewDAO); reset(extractedArchiveDir); expect(extractedArchiveDir.exists()).andReturn(false); expect(extractedArchiveDir.mkdir()).andReturn(true); replay(extractedArchiveDir); viewExtractor = getViewExtractor(viewDefinition); if (System.getProperty("os.name").contains("Windows")) { Assert.assertTrue(viewExtractor.ensureExtractedArchiveDirectory("\\var\\lib\\ambari-server\\resources\\views\\work")); } else { Assert.assertTrue(viewExtractor.ensureExtractedArchiveDirectory("/var/lib/ambari-server/resources/views/work")); } verify(extractedArchiveDir); reset(extractedArchiveDir); expect(extractedArchiveDir.exists()).andReturn(false); expect(extractedArchiveDir.mkdir()).andReturn(false); replay(extractedArchiveDir); viewExtractor = getViewExtractor(viewDefinition); if (System.getProperty("os.name").contains("Windows")) { Assert.assertFalse(viewExtractor.ensureExtractedArchiveDirectory("\\var\\lib\\ambari-server\\resources\\views\\work")); } else { Assert.assertFalse(viewExtractor.ensureExtractedArchiveDirectory("/var/lib/ambari-server/resources/views/work")); } verify(extractedArchiveDir); } private ViewExtractor getViewExtractor(ViewEntity viewDefinition) throws Exception { Map<File, ViewConfig> viewConfigs = Collections.singletonMap(viewArchive, viewDefinition.getConfiguration()); Map<String, File> files = new HashMap<>(); if (System.getProperty("os.name").contains("Windows")) { files.put("\\var\\lib\\ambari-server\\resources\\views\\work", extractedArchiveDir); files.put("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}", archiveDir); files.put("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}\\view.xml", entryFile); files.put("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}\\WEB-INF/classes", classesDir); files.put("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}\\WEB-INF/lib", libDir); files.put("\\var\\lib\\ambari-server\\resources\\views\\work\\MY_VIEW{1.0.0}\\META-INF", metaInfDir); } else { files.put("/var/lib/ambari-server/resources/views/work", extractedArchiveDir); files.put("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}", archiveDir); files.put("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}/view.xml", entryFile); files.put("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}/WEB-INF/classes", classesDir); files.put("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}/WEB-INF/lib", libDir); files.put("/var/lib/ambari-server/resources/views/work/MY_VIEW{1.0.0}/META-INF", metaInfDir); } Map<File, FileOutputStream> outputStreams = new HashMap<>(); outputStreams.put(entryFile, fos); Map<File, JarInputStream> jarFiles = new HashMap<>(); jarFiles.put(viewArchive, viewJarFile); TestViewArchiveUtility archiveUtility = new TestViewArchiveUtility(viewConfigs, files, outputStreams, jarFiles); ViewExtractor viewExtractor = new ViewExtractor(); viewExtractor.archiveUtility = archiveUtility; return viewExtractor; } public static class TestViewArchiveUtility extends ViewArchiveUtility { private final Map<File, ViewConfig> viewConfigs; private final Map<String, File> files; private final Map<File, FileOutputStream> outputStreams; private final Map<File, JarInputStream> jarFiles; public TestViewArchiveUtility(Map<File, ViewConfig> viewConfigs, Map<String, File> files, Map<File, FileOutputStream> outputStreams, Map<File, JarInputStream> jarFiles) { this.viewConfigs = viewConfigs; this.files = files; this.outputStreams = outputStreams; this.jarFiles = jarFiles; } @Override public ViewConfig getViewConfigFromArchive(File archiveFile) throws MalformedURLException, JAXBException { return viewConfigs.get(archiveFile); } @Override public ViewConfig getViewConfigFromExtractedArchive(String archivePath, boolean validate) throws JAXBException, FileNotFoundException { for (File viewConfigKey: viewConfigs.keySet()) { if (viewConfigKey.getAbsolutePath().equals(archivePath)) { return viewConfigs.get(viewConfigKey); } } return null; } @Override public File getFile(String path) { return files.get(path); } @Override public FileOutputStream getFileOutputStream(File file) throws FileNotFoundException { return outputStreams.get(file); } @Override public JarInputStream getJarFileStream(File file) throws IOException { return jarFiles.get(file); } } }