/* * * Copyright 2016 Netflix, 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. * */ package com.netflix.genie.web.resources.writers; import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.genie.test.categories.UnitTest; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.mockito.Mockito; import org.w3c.tidy.Tidy; import java.io.ByteArrayInputStream; import java.io.File; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.Charset; import java.util.Date; import java.util.UUID; /** * Unit tests for the DefaultDirectoryWriter. * * @author tgianos * @since 3.0.0 */ @Category(UnitTest.class) public class DefaultDirectoryWriterUnitTests { private static final String REQUEST_URL_BASE = "http://genie.netflix.com:8080/api/v3/jobs/" + UUID.randomUUID().toString() + "/output"; private static final String REQUEST_URL_WITH_PARENT = REQUEST_URL_BASE + "/" + UUID.randomUUID().toString(); private static final long PARENT_SIZE = 0L; private static final Date PARENT_LAST_MODIFIED = new Date(); private static final String PARENT_NAME = "../"; private static final String PARENT_URL = REQUEST_URL_BASE; private static final long DIR_1_SIZE = 0L; private static final Date DIR_1_LAST_MODIFIED = new Date(new Date().getTime() + 13142); private static final String DIR_1_NAME = UUID.randomUUID().toString(); private static final String DIR_1_URL = REQUEST_URL_WITH_PARENT + "/" + DIR_1_NAME; private static final long DIR_2_SIZE = 0L; private static final Date DIR_2_LAST_MODIFIED = new Date(new Date().getTime() - 1830); private static final String DIR_2_NAME = UUID.randomUUID().toString(); private static final String DIR_2_URL = REQUEST_URL_WITH_PARENT + "/" + DIR_2_NAME; private static final long FILE_1_SIZE = 73522431; private static final Date FILE_1_LAST_MODIFIED = new Date(new Date().getTime() + 1832430); private static final String FILE_1_NAME = UUID.randomUUID().toString(); private static final String FILE_1_URL = REQUEST_URL_WITH_PARENT + "/" + FILE_1_NAME; private static final long FILE_2_SIZE = 735231; private static final Date FILE_2_LAST_MODIFIED = new Date(new Date().getTime() + 1832443); private static final String FILE_2_NAME = UUID.randomUUID().toString(); private static final String FILE_2_URL = REQUEST_URL_WITH_PARENT + "/" + FILE_2_NAME; private DefaultDirectoryWriter writer; private File directory; private DefaultDirectoryWriter.Entry directoryEntry1; private DefaultDirectoryWriter.Entry directoryEntry2; private DefaultDirectoryWriter.Entry fileEntry1; private DefaultDirectoryWriter.Entry fileEntry2; /** * Setup the tests. */ @Before public void setup() { this.writer = new DefaultDirectoryWriter(); this.directory = Mockito.mock(File.class); Mockito.when(this.directory.isDirectory()).thenReturn(true); final String slash = "/"; this.directoryEntry1 = new DefaultDirectoryWriter.Entry(); this.directoryEntry1.setLastModified(DIR_1_LAST_MODIFIED); this.directoryEntry1.setSize(DIR_1_SIZE); this.directoryEntry1.setUrl(DIR_1_URL + slash); this.directoryEntry1.setName(DIR_1_NAME + slash); this.directoryEntry2 = new DefaultDirectoryWriter.Entry(); this.directoryEntry2.setLastModified(DIR_2_LAST_MODIFIED); this.directoryEntry2.setSize(DIR_2_SIZE); this.directoryEntry2.setUrl(DIR_2_URL + slash); this.directoryEntry2.setName(DIR_2_NAME + slash); this.fileEntry1 = new DefaultDirectoryWriter.Entry(); this.fileEntry1.setLastModified(FILE_1_LAST_MODIFIED); this.fileEntry1.setSize(FILE_1_SIZE); this.fileEntry1.setUrl(FILE_1_URL); this.fileEntry1.setName(FILE_1_NAME); this.fileEntry2 = new DefaultDirectoryWriter.Entry(); this.fileEntry2.setLastModified(FILE_2_LAST_MODIFIED); this.fileEntry2.setSize(FILE_2_SIZE); this.fileEntry2.setUrl(FILE_2_URL); this.fileEntry2.setName(FILE_2_NAME); } /** * Make sure if the argument passed in isn't a directory an exception is thrown. */ @Test(expected = IllegalArgumentException.class) public void cantGetDirectoryWithoutValidDirectory() { Mockito.when(this.directory.isDirectory()).thenReturn(false); this.writer.getDirectory(this.directory, UUID.randomUUID().toString(), false); } /** * Make sure an exception is thrown when no request URL is passed in to the method. */ @Test(expected = IllegalArgumentException.class) public void cantGetDirectoryWithoutRequestUrl() { this.writer.getDirectory(this.directory, null, false); } /** * Make sure can get a directory with a parent. */ @Test public void canGetDirectoryWithParent() { this.setupWithParent(); final DefaultDirectoryWriter.Directory dir = this.writer.getDirectory(this.directory, REQUEST_URL_WITH_PARENT, true); Assert.assertThat(dir.getParent(), Matchers.notNullValue()); Assert.assertThat(dir.getParent().getName(), Matchers.is(PARENT_NAME)); Assert.assertThat(dir.getParent().getUrl(), Matchers.is(PARENT_URL)); Assert.assertThat(dir.getParent().getSize(), Matchers.is(PARENT_SIZE)); Assert.assertThat(dir.getParent().getLastModified(), Matchers.is(PARENT_LAST_MODIFIED)); Assert.assertThat(dir.getDirectories(), Matchers.notNullValue()); Assert.assertThat(dir.getDirectories().size(), Matchers.is(2)); Assert.assertThat( dir.getDirectories(), Matchers.containsInAnyOrder(this.directoryEntry1, this.directoryEntry2) ); Assert.assertThat(dir.getFiles(), Matchers.notNullValue()); Assert.assertThat(dir.getFiles().size(), Matchers.is(2)); Assert.assertThat( dir.getFiles(), Matchers.containsInAnyOrder(this.fileEntry1, this.fileEntry2) ); } /** * Make sure can get a directory without a parent. */ @Test public void canGetDirectoryWithoutParent() { this.setupWithoutParent(); final DefaultDirectoryWriter.Directory dir = this.writer.getDirectory(this.directory, REQUEST_URL_BASE, false); Assert.assertThat(dir.getParent(), Matchers.nullValue()); Assert.assertThat(dir.getDirectories(), Matchers.notNullValue()); Assert.assertTrue(dir.getDirectories().isEmpty()); Assert.assertThat(dir.getFiles(), Matchers.notNullValue()); Assert.assertTrue(dir.getFiles().isEmpty()); } /** * Make sure can get html representation of the directory. * * @throws Exception on any problem */ @Test public void canConvertToHtml() throws Exception { this.setupWithParent(); final String html = this.writer.toHtml(this.directory, REQUEST_URL_WITH_PARENT, true); Assert.assertThat(html, Matchers.notNullValue()); // Not going to parse the whole HTML to validate contents, too much work. // So just make sure HTML is valid so at least it doesn't cause error in browser final Tidy tidy = new Tidy(); final Writer stringWriter = new StringWriter(); tidy.parse(new ByteArrayInputStream(html.getBytes(Charset.forName("UTF-8"))), stringWriter); Assert.assertThat(tidy.getParseErrors(), Matchers.is(0)); Assert.assertThat(tidy.getParseWarnings(), Matchers.is(0)); } /** * Make sure can get a json representation of the directory. * * @throws Exception on any problem */ @Test public void canConvertToJson() throws Exception { this.setupWithParent(); final String json = this.writer.toJson(this.directory, REQUEST_URL_WITH_PARENT, true); Assert.assertThat(json, Matchers.notNullValue()); final ObjectMapper mapper = new ObjectMapper(); final DefaultDirectoryWriter.Directory dir = mapper.readValue(json, DefaultDirectoryWriter.Directory.class); Assert.assertThat(dir.getParent(), Matchers.notNullValue()); Assert.assertThat(dir.getParent().getName(), Matchers.is(PARENT_NAME)); Assert.assertThat(dir.getParent().getUrl(), Matchers.is(PARENT_URL)); Assert.assertThat(dir.getParent().getSize(), Matchers.is(PARENT_SIZE)); Assert.assertThat(dir.getParent().getLastModified(), Matchers.is(PARENT_LAST_MODIFIED)); Assert.assertThat(dir.getDirectories(), Matchers.notNullValue()); Assert.assertThat(dir.getDirectories().size(), Matchers.is(2)); Assert.assertThat( dir.getDirectories(), Matchers.containsInAnyOrder(this.directoryEntry1, this.directoryEntry2) ); Assert.assertThat(dir.getFiles(), Matchers.notNullValue()); Assert.assertThat(dir.getFiles().size(), Matchers.is(2)); Assert.assertThat( dir.getFiles(), Matchers.containsInAnyOrder(this.fileEntry1, this.fileEntry2) ); } private void setupWithoutParent() { Mockito.when(this.directory.listFiles()).thenReturn(null); } private void setupWithParent() { final File parent = Mockito.mock(File.class); final File absoluteParent = Mockito.mock(File.class); Mockito.when(parent.getAbsoluteFile()).thenReturn(absoluteParent); Mockito.when(absoluteParent.length()).thenReturn(PARENT_SIZE); Mockito.when(absoluteParent.lastModified()).thenReturn(PARENT_LAST_MODIFIED.getTime()); Mockito.when(parent.getName()).thenReturn(PARENT_NAME); Mockito.when(this.directory.getParentFile()).thenReturn(parent); final File dir1 = Mockito.mock(File.class); final File absoluteDir1 = Mockito.mock(File.class); Mockito.when(dir1.getAbsoluteFile()).thenReturn(absoluteDir1); Mockito.when(absoluteDir1.length()).thenReturn(DIR_1_SIZE); Mockito.when(absoluteDir1.lastModified()).thenReturn(DIR_1_LAST_MODIFIED.getTime()); Mockito.when(dir1.getName()).thenReturn(DIR_1_NAME); Mockito.when(dir1.isDirectory()).thenReturn(true); final File dir2 = Mockito.mock(File.class); final File absoluteDir2 = Mockito.mock(File.class); Mockito.when(dir2.getAbsoluteFile()).thenReturn(absoluteDir2); Mockito.when(absoluteDir2.length()).thenReturn(DIR_2_SIZE); Mockito.when(absoluteDir2.lastModified()).thenReturn(DIR_2_LAST_MODIFIED.getTime()); Mockito.when(dir2.getName()).thenReturn(DIR_2_NAME); Mockito.when(dir2.isDirectory()).thenReturn(true); final File file1 = Mockito.mock(File.class); final File absoluteFile1 = Mockito.mock(File.class); Mockito.when(file1.getAbsoluteFile()).thenReturn(absoluteFile1); Mockito.when(absoluteFile1.length()).thenReturn(FILE_1_SIZE); Mockito.when(absoluteFile1.lastModified()).thenReturn(FILE_1_LAST_MODIFIED.getTime()); Mockito.when(file1.getName()).thenReturn(FILE_1_NAME); Mockito.when(file1.isDirectory()).thenReturn(false); final File file2 = Mockito.mock(File.class); final File absoluteFile2 = Mockito.mock(File.class); Mockito.when(file2.getAbsoluteFile()).thenReturn(absoluteFile2); Mockito.when(absoluteFile2.length()).thenReturn(FILE_2_SIZE); Mockito.when(absoluteFile2.lastModified()).thenReturn(FILE_2_LAST_MODIFIED.getTime()); Mockito.when(file2.getName()).thenReturn(FILE_2_NAME); Mockito.when(file2.isDirectory()).thenReturn(false); final File[] files = new File[]{dir1, file1, dir2, file2}; Mockito.when(this.directory.listFiles()).thenReturn(files); } }