// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.application.provider; import com.yahoo.config.application.TestBase; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.Zone; import com.yahoo.io.IOUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.file.Files; import static com.yahoo.config.model.application.provider.FilesApplicationPackage.applicationFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author Ulf Lilleengen */ public class FilesApplicationPackageTest { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Test public void testPreprocessing() throws IOException { File appDir = temporaryFolder.newFolder(); IOUtils.copyDirectory(new File("src/test/resources/multienvapp"), appDir); assertTrue(new File(appDir, "services.xml").exists()); assertTrue(new File(appDir, "hosts.xml").exists()); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); ApplicationPackage processed = app.preprocess(new Zone(Environment.dev, RegionName.defaultName()), new BaseDeployLogger()); assertTrue(new File(appDir, ".preprocessed").exists()); String expectedServices = """ 1 """; TestBase.assertDocument(expectedServices, processed.getServices()); String expectedHosts = """ node1 """; TestBase.assertDocument(expectedHosts, processed.getHosts()); } @Test public void testDeploymentXmlNotAvailable() { File appDir = new File("src/test/resources/multienvapp"); assertFalse(new File(appDir, "deployment.xml").exists()); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); assertFalse(app.getDeployment().isPresent()); assertTrue(app.getDeploymentSpec().isEmpty()); } @Test public void testDeploymentXml() throws IOException { File appDir = new File("src/test/resources/app-with-deployment"); final File deployment = new File(appDir, "deployment.xml"); assertTrue(deployment.exists()); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); assertTrue(app.getDeployment().isPresent()); assertFalse(app.getDeploymentSpec().isEmpty()); assertFalse(app.getMajorVersion().isPresent()); assertEquals(IOUtils.readAll(app.getDeployment().get()), IOUtils.readAll(new FileReader(deployment))); } @Test public void testPinningMajorVersion() throws IOException { File appDir = new File("src/test/resources/app-pinning-major-version"); final File deployment = new File(appDir, "deployment.xml"); assertTrue(deployment.exists()); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); assertTrue(app.getDeployment().isPresent()); assertTrue(app.getMajorVersion().isPresent()); assertEquals(6, (int)app.getMajorVersion().get()); assertEquals(IOUtils.readAll(app.getDeployment().get()), IOUtils.readAll(new FileReader(deployment))); } @Test public void testLegacyOverrides() { File appDir = new File("src/test/resources/app-legacy-overrides"); ApplicationPackage app = FilesApplicationPackage.fromFile(appDir); var overrides = app.legacyOverrides(); assertEquals(2, overrides.size()); assertEquals("something here", overrides.get("foo-bar")); assertEquals("false", overrides.get("v7-geo-positions")); } @Test public void failOnEmptyServicesXml() throws IOException { File appDir = temporaryFolder.newFolder(); IOUtils.copyDirectory(new File("src/test/resources/multienvapp"), appDir); Files.delete(new File(appDir, "services.xml").toPath()); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); try { app.preprocess(new Zone(Environment.dev, RegionName.defaultName()), new BaseDeployLogger()); fail(); } catch (IllegalArgumentException e) { assertTrue(e.getMessage().contains("services.xml in application package is empty")); } } @Test public void testApplicationFile() { applicationFile(new File("foo"), ""); applicationFile(new File("foo"), "bar"); applicationFile(new File(new File(""), ""), ""); assertEquals("/ is not a child of ", assertThrows(IllegalArgumentException.class, () -> applicationFile(new File(""), "")) .getMessage()); assertEquals("'..' is not allowed in path", assertThrows(IllegalArgumentException.class, () -> applicationFile(new File("foo"), "..")) .getMessage()); } @Test public void testValidFileExtensions() { File appDir = new File("src/test/resources/app-with-deployment"); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); app.validateFileExtensions(); } @Test public void testInvalidFileExtensions() { File appDir = new File("src/test/resources/app-with-invalid-files-in-subdir"); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); try { app.validateFileExtensions(); fail("expected an exception"); } catch (IllegalArgumentException e) { assertEquals("File in application package with unknown extension: search/query-profiles/file-with-invalid.extension, " + "please delete or move file to another directory.", e.getMessage()); } } @Test public void testInvalidFileExtensionInSubDirOfSubDir() { File appDir = new File("src/test/resources/app-with-files-with-invalid-extension-in-subdir-of-subdir/"); FilesApplicationPackage app = FilesApplicationPackage.fromFile(appDir); try { app.validateFileExtensions(); fail("expected an exception"); } catch (IllegalArgumentException e) { assertEquals("File in application package with unknown extension: schemas/foo/bar.junk, " + "please delete or move file to another directory.", e.getMessage()); } } }