/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* 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.asakusafw.testdriver.directio;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.hadoop.io.Text;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.asakusafw.runtime.directio.DataFormat;
import com.asakusafw.runtime.directio.hadoop.HadoopDataSource;
import com.asakusafw.runtime.directio.hadoop.HadoopDataSourceProfile;
import com.asakusafw.testdriver.core.DataModelReflection;
import com.asakusafw.testdriver.core.DataModelSource;
import com.asakusafw.testdriver.core.SpiExporterRetriever;
/**
* Test for {@link DirectFileOutputRetriever}.
*/
@RunWith(Parameterized.class)
public class DirectFileOutputRetrieverTest {
/**
* Profile context.
*/
@Rule
public final ProfileContext profile = new ProfileContext();
/**
* A temporary folder.
*/
@Rule
public final TemporaryFolder folder = new TemporaryFolder();
private final Class<? extends DataFormat<Text>> format;
/**
* Returns the parameters.
* @return the parameters
*/
@Parameters
public static List<Object[]> data() {
return Arrays.asList(new Object[][] {
{ MockStreamFormat.class },
{ MockFileFormat.class },
});
}
/**
* Creates a new instance.
* @param format the format.
*/
public DirectFileOutputRetrieverTest(Class<? extends DataFormat<Text>> format) {
this.format = format;
}
/**
* truncate.
* @throws Exception if failed
*/
@Test
public void truncate() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
File file = put("base/hoge.txt", "Hello, world!");
File deep = put("base/d/e/e/p/hoge.txt", "Hello, world!");
File outer = put("outer/hoge.txt", "Hello, world!");
assertThat(file.exists(), is(true));
assertThat(deep.exists(), is(true));
assertThat(outer.exists(), is(true));
testee.truncate(
new MockOutputDescription("base", "something", format),
profile.getTextContext());
assertThat(file.exists(), is(false));
assertThat(deep.exists(), is(false));
assertThat(outer.exists(), is(true));
}
/**
* truncate with placeholders.
* @throws Exception if failed
*/
@Test
public void truncate_placeholders() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
File file = put("base/hoge.txt", "Hello, world!");
File deep = put("base/d/e/e/p/hoge.txt", "Hello, world!");
File outer = put("outer/hoge.txt", "Hello, world!");
assertThat(file.exists(), is(true));
assertThat(deep.exists(), is(true));
assertThat(outer.exists(), is(true));
testee.truncate(
new MockOutputDescription("base", "output-{id}", format),
profile.getTextContext());
assertThat(file.exists(), is(false));
assertThat(deep.exists(), is(false));
assertThat(outer.exists(), is(true));
}
/**
* truncate with wildcard.
* @throws Exception if failed
*/
@Test
public void truncate_wildcard() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
File file = put("base/hoge.txt", "Hello, world!");
File deep = put("base/d/e/e/p/hoge.txt", "Hello, world!");
File outer = put("outer/hoge.txt", "Hello, world!");
assertThat(file.exists(), is(true));
assertThat(deep.exists(), is(true));
assertThat(outer.exists(), is(true));
testee.truncate(
new MockOutputDescription("base", "output-*", format),
profile.getTextContext());
assertThat(file.exists(), is(false));
assertThat(deep.exists(), is(false));
assertThat(outer.exists(), is(true));
}
/**
* truncate empty target.
* @throws Exception if failed
*/
@Test
public void truncate_empty() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
testee.truncate(
new MockOutputDescription("base", "something", format),
profile.getTextContext());
}
/**
* truncate with variables in path.
* @throws Exception if failed
*/
@Test
public void truncate_variable() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
File file = put("base/hoge.txt", "Hello, world!");
File deep = put("base/d/e/e/p/hoge.txt", "Hello, world!");
File outer = put("outer/hoge.txt", "Hello, world!");
assertThat(file.exists(), is(true));
assertThat(deep.exists(), is(true));
assertThat(outer.exists(), is(true));
testee.truncate(
new MockOutputDescription("${target}", "something", format),
profile.getTextContext("target", "base"));
assertThat(file.exists(), is(false));
assertThat(deep.exists(), is(false));
assertThat(outer.exists(), is(true));
}
/**
* simple input.
* @throws Exception if failed
*/
@Test
public void createInput() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
put("base/output.txt", "Hello, world!");
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("base", "output.txt", format),
profile.getTextContext());
List<String> list = get(input);
assertThat(list, is(Arrays.asList("Hello, world!")));
}
/**
* output multiple records.
* @throws Exception if failed
*/
@Test
public void createInput_multirecord() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
put("base/output.txt", "Hello1", "Hello2", "Hello3");
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("base", "output.txt", format),
profile.getTextContext());
List<String> list = get(input);
assertThat(list.size(), is(3));
assertThat(list, hasItem("Hello1"));
assertThat(list, hasItem("Hello2"));
assertThat(list, hasItem("Hello3"));
}
/**
* output multiple files.
* @throws Exception if failed
*/
@Test
public void createInput_multifile() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
put("base/output-1.txt", "Hello1");
put("base/output-2.txt", "Hello2");
put("base/output-3.txt", "Hello3");
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("base", "{value}.txt", format),
profile.getTextContext());
List<String> list = get(input);
assertThat(list.size(), is(3));
assertThat(list, hasItem("Hello1"));
assertThat(list, hasItem("Hello2"));
assertThat(list, hasItem("Hello3"));
}
/**
* output with variables.
* @throws Exception if failed
*/
@Test
public void createInput_variables() throws Exception {
profile.add("vars", HadoopDataSource.class, "base");
profile.add("vars", new File(folder.getRoot(), "testing"));
profile.put();
put("testing/output.txt", "Hello, world!");
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("${vbase}", "${voutput}.txt", format),
profile.getTextContext("vbase", "base", "voutput", "output"));
List<String> list = get(input);
assertThat(list, is(Arrays.asList("Hello, world!")));
}
/**
* output with placeholders.
* @throws Exception if failed
*/
@Test
public void createInput_placeholders() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
put("base/output-1.txt", "Hello1");
put("base/output-2.txt", "Hello2");
put("base/output-3.txt", "Hello3");
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("base", "output-{id}.txt", format),
profile.getTextContext());
List<String> list = get(input);
assertThat(list.size(), is(3));
assertThat(list, hasItem("Hello1"));
assertThat(list, hasItem("Hello2"));
assertThat(list, hasItem("Hello3"));
}
/**
* output with wildcard.
* @throws Exception if failed
*/
@Test
public void createInput_wildcard() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
put("base/output-1.txt", "Hello1");
put("base/output-2.txt", "Hello2");
put("base/output-3.txt", "Hello3");
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("base", "output-*.txt", format),
profile.getTextContext());
List<String> list = get(input);
assertThat(list.size(), is(3));
assertThat(list, hasItem("Hello1"));
assertThat(list, hasItem("Hello2"));
assertThat(list, hasItem("Hello3"));
}
/**
* configuration is not found.
* @throws Exception if failed
*/
@Test(expected = IOException.class)
public void no_config() throws Exception {
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
testee.truncate(
new MockOutputDescription("base", "something", format),
profile.getTextContext());
}
/**
* datasource is not found.
* @throws Exception if failed
*/
@Test(expected = IOException.class)
public void no_datasource() throws Exception {
profile.add("root", HadoopDataSource.class, "other");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
DirectFileOutputRetriever testee = new DirectFileOutputRetriever();
testee.truncate(
new MockOutputDescription("base", "something", format),
profile.getTextContext());
}
/**
* using SPI.
* @throws Exception if failed
*/
@Test
public void spi() throws Exception {
profile.add("root", HadoopDataSource.class, "/");
profile.add("root", HadoopDataSourceProfile.KEY_PATH, folder.getRoot().toURI().toURL().toString());
profile.put();
put("base/output.txt", "Hello, world!");
SpiExporterRetriever testee = new SpiExporterRetriever(getClass().getClassLoader());
DataModelSource input = testee.createSource(
new MockTextDefinition(),
new MockOutputDescription("base", "output.txt", format),
profile.getTextContext());
List<String> list = get(input);
assertThat(list, is(Arrays.asList("Hello, world!")));
}
private List<String> get(DataModelSource input) throws IOException {
try {
MockTextDefinition def = new MockTextDefinition();
List<String> results = new ArrayList<>();
while (true) {
DataModelReflection next = input.next();
if (next == null) {
break;
}
results.add(def.toObject(next).toString());
}
return results;
} finally {
input.close();
}
}
private File put(String targetPath, String... contents) throws IOException {
File target = new File(folder.getRoot(), targetPath);
target.getParentFile().mkdirs();
try (PrintWriter w = new PrintWriter(target, "UTF-8")) {
for (String line : contents) {
w.println(line);
}
}
return target;
}
}