/*
* 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.pig.test;
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.List;
import java.util.Iterator;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Method;
import org.apache.pig.ExecType;
import org.apache.pig.PigServer;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import junit.framework.TestCase;
public class TestPigServer extends TestCase {
private PigServer pig = null;
MiniCluster cluster = MiniCluster.buildCluster();
private File stdOutRedirectedFile;
@Before
@Override
public void setUp() throws Exception{
pig = new PigServer(ExecType.MAPREDUCE, cluster.getProperties());
stdOutRedirectedFile = new File("stdout.redirected");
// Create file if it does not exist
try {
if(!stdOutRedirectedFile.createNewFile())
fail("Unable to create input files");
} catch (IOException e) {
fail("Unable to create input files:" + e.getMessage());
}
}
@After
@Override
public void tearDown() throws Exception{
pig = null;
stdOutRedirectedFile.delete();
}
private final static String FILE_SEPARATOR = System.getProperty("file.separator");
// make sure that name is included or not (depending on flag "included")
// in the given list of stings
private static void verifyStringContained(List<URL> list, String name, boolean included) {
Iterator<URL> iter = list.iterator();
boolean nameIsSubstring = false;
int count = 0;
while (iter.hasNext()) {
if (iter.next().toString().contains(name)) {
nameIsSubstring = true;
++count;
}
}
if (included) {
assertTrue(nameIsSubstring);
assertTrue(count == 1);
}
else {
assertFalse(nameIsSubstring);
}
}
// creates an empty jar file
private static void createFakeJarFile(String location, String name)
throws IOException {
assertFalse((new File(name)).canRead());
assertTrue((new File(location)).mkdirs());
assertTrue((new File(location + FILE_SEPARATOR + name)).
createNewFile());
}
// dynamically add more resources to the system class loader
private static void registerNewResource(String file) throws Exception {
URL urlToAdd = new File(file).toURI().toURL();
URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method addMethod = URLClassLoader.class.
getDeclaredMethod("addURL",
new Class[]{URL.class});
addMethod.setAccessible(true);
addMethod.invoke(sysLoader, new Object[]{urlToAdd});
}
private static void executeShellCommand(String cmd) throws Exception {
Process cmdProc = Runtime.getRuntime().exec(cmd);
cmdProc.waitFor();
assertTrue(cmdProc.exitValue() == 0);
}
/**
* The jar file to register is not present
*/
@Test
public void testRegisterJarFileNotPresent() throws Throwable {
// resister a jar file that does not exist
String jarName = "BadFileNameTestJarNotPresent.jar";
// jar name is not present to start with
verifyStringContained(pig.getPigContext().extraJars, jarName, false);
boolean exceptionRaised = false;
try {
pig.registerJar(jarName);
}
catch (IOException e) {
exceptionRaised = true;
}
assertTrue(exceptionRaised);
verifyStringContained(pig.getPigContext().extraJars, jarName, false);
}
/**
* Jar file to register is not present in the system resources
* in this case name of jar file is relative to current working dir
*/
@Test
public void testRegisterJarLocalDir() throws Throwable {
String dir1 = "test1_register_jar_local";
String dir2 = "test2_register_jar_local";
String jarLocation = dir1 + FILE_SEPARATOR +
dir2 + FILE_SEPARATOR;
String jarName = "TestRegisterJarLocal.jar";
createFakeJarFile(jarLocation, jarName);
verifyStringContained(pig.getPigContext().extraJars, jarName, false);
boolean exceptionRaised = false;
try {
pig.registerJar(jarLocation + jarName);
}
catch (IOException e) {
exceptionRaised = true;
}
assertFalse(exceptionRaised);
verifyStringContained(pig.getPigContext().extraJars, jarName, true);
// clean-up
assertTrue((new File(jarLocation + jarName)).delete());
(new File(dir1 + FILE_SEPARATOR + dir2)).delete();
(new File(dir1)).delete();
}
/**
* Jar file is located via system resources
* Test verifies that even with multiple resources matching,
* only one of them is registered.
*/
@Test
public void testRegisterJarFromResources () throws Throwable {
String dir = "test_register_jar_res_dir";
String subDir1 = "test_register_jar_res_sub_dir1";
String subDir2 = "test_register_jar_res_sub_dir2";
String jarName = "TestRegisterJarFromRes.jar";
String jarLocation1 = dir + FILE_SEPARATOR + subDir1 + FILE_SEPARATOR;
String jarLocation2 = dir + FILE_SEPARATOR + subDir2 + FILE_SEPARATOR;
createFakeJarFile(jarLocation1, jarName);
createFakeJarFile(jarLocation2, jarName);
verifyStringContained(pig.getPigContext().extraJars, jarName, false);
registerNewResource(jarLocation1);
registerNewResource(jarLocation2);
boolean exceptionRaised = false;
try {
pig.registerJar(jarName);
}
catch (IOException e) {
exceptionRaised = true;
}
assertFalse(exceptionRaised);
verifyStringContained(pig.getPigContext().extraJars, jarName, true);
// clean-up
assertTrue((new File(jarLocation1 + jarName)).delete());
assertTrue((new File(jarLocation2 + jarName)).delete());
(new File(jarLocation1)).delete();
(new File(jarLocation2)).delete();
(new File(dir)).delete();
}
/**
* Use a resource inside a jar file.
* Verify that the containing jar file is registered correctly.
* @throws Exception
*/
@Test
public void testRegisterJarResourceInJar() throws Throwable {
String dir = "test_register_jar_res_in_jar";
String subDir = "sub_dir";
String jarName = "TestRegisterJarNonEmpty.jar";
String className = "TestRegisterJar";
String javaSrc = "package " + subDir + "; class " + className + " { }";
// create dirs
(new File(dir + FILE_SEPARATOR + subDir)).mkdirs();
// generate java file
FileOutputStream outStream =
new FileOutputStream(new File(dir + FILE_SEPARATOR + subDir +
FILE_SEPARATOR + className + ".java"));
OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
outWriter.write(javaSrc);
outWriter.close();
// compile
executeShellCommand("javac " + dir + FILE_SEPARATOR + subDir +
FILE_SEPARATOR + className + ".java");
// remove src file
(new File(dir + FILE_SEPARATOR + subDir +
FILE_SEPARATOR + className + ".java")).delete();
// generate jar file
executeShellCommand("jar -cf " + dir + FILE_SEPARATOR + jarName + " " +
"-C " + dir + " " + subDir);
// remove class file and sub_dir
(new File(dir + FILE_SEPARATOR + subDir +
FILE_SEPARATOR + className + ".class")).delete();
(new File(dir + FILE_SEPARATOR + subDir)).delete();
// register resource
registerNewResource(dir + FILE_SEPARATOR + jarName);
// load the specific resource
boolean exceptionRaised = false;
try {
pig.registerJar("sub_dir/TestRegisterJar.class");
}
catch (IOException e) {
exceptionRaised = true;
}
// verify proper jar file is located
assertFalse(exceptionRaised);
verifyStringContained(pig.getPigContext().extraJars, jarName, true);
// clean up Jar file and test dir
(new File(dir + FILE_SEPARATOR + jarName)).delete();
(new File(dir)).delete();
}
@Test
public void testDescribeLoad() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
System.setOut(out);
pig.dumpSchema("a") ;
out.close(); // Remember this!
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("a: {field1: int,field2: float,field3: chararray}") == true);
}
reader.close();
}
@Test
public void testDescribeFilter() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = filter a by field1 > 10;") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close(); // Remember this!
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("b: {field1: int,field2: float,field3: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeDistinct() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = distinct a ;") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close(); // Remember this!
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("b: {field1: int,field2: float,field3: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeSort() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = order a by * desc;") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close(); // Remember this!
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("b: {field1: int,field2: float,field3: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeLimit() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = limit a 10;") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close(); // Remember this!
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("b: {field1: int,field2: float,field3: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeForeach() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = foreach a generate field1 + 10;") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("b: {int}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeForeachFail() throws Throwable {
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = foreach a generate field1 + 10;") ;
try {
pig.dumpSchema("c") ;
fail("Error expected");
} catch (Exception e) {
assertTrue(e.getMessage().contains("Unable to describe schema for alias c"));
}
}
@Test
public void testDescribeForeachNoSchema() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' ;") ;
pig.registerQuery("b = foreach a generate *;") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("Schema for b unknown.") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeCogroup() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = load 'b' as (field4, field5: double, field6: chararray );") ;
pig.registerQuery("c = cogroup a by field1, b by field4;") ;
System.setOut(out);
pig.dumpSchema("c") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("c: {group: int,a: {field1: int,field2: float,field3: chararray},b: {field4: bytearray,field5: double,field6: chararray}}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeCross() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = load 'b' as (field4, field5: double, field6: chararray );") ;
pig.registerQuery("c = cross a, b;") ;
System.setOut(out);
pig.dumpSchema("c") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("c: {a::field1: int,a::field2: float,a::field3: chararray,b::field4: bytearray,b::field5: double,b::field6: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeJoin() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = load 'b' as (field4, field5: double, field6: chararray );") ;
pig.registerQuery("c = join a by field1, b by field4;") ;
System.setOut(out);
pig.dumpSchema("c") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("c: {a::field1: int,a::field2: float,a::field3: chararray,b::field4: bytearray,b::field5: double,b::field6: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeUnion() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (field1: int, field2: float, field3: chararray );") ;
pig.registerQuery("b = load 'b' as (field4, field5: double, field6: chararray );") ;
pig.registerQuery("c = union a, b;") ;
System.setOut(out);
pig.dumpSchema("c") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
assertTrue(s.equals("c: {field1: int,field2: double,field3: chararray}") == true);
}
fileWithStdOutContents.close();
}
@Test
public void testDescribeComplex() throws Throwable {
PrintStream console = System.out;
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(stdOutRedirectedFile)));
pig.registerQuery("a = load 'a' as (site: chararray, count: int, itemCounts: bag { itemCountsTuple: tuple (type: chararray, typeCount: int, f: float, m: map[]) } ) ;") ;
pig.registerQuery("b = foreach a generate site, count, FLATTEN(itemCounts);") ;
System.setOut(out);
pig.dumpSchema("b") ;
out.close();
System.setOut(console);
String s;
InputStream fileWithStdOutContents = new DataInputStream( new BufferedInputStream( new FileInputStream(stdOutRedirectedFile)));
BufferedReader reader = new BufferedReader(new InputStreamReader(fileWithStdOutContents));
while ((s = reader.readLine()) != null) {
// strip away the initial schema alias and the
// curlies surrounding the schema to construct
// the schema object from the schema string
s = s.replaceAll("^.*\\{", "");
s = s.replaceAll("\\}$", "");
Schema actual = Util.getSchemaFromString( s);
Schema expected = Util.getSchemaFromString(
"site: chararray,count: int," +
"itemCounts::type: chararray,itemCounts::typeCount: int," +
"itemCounts::f: float,itemCounts::m: map[ ]");
assertEquals(expected, actual);
}
fileWithStdOutContents.close();
}
}