AbstractTestNativeRemoteFunctions.java
/*
* 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.facebook.presto.nativeworker;
import com.facebook.presto.testing.QueryRunner;
import com.facebook.presto.tests.AbstractTestQueryFramework;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static com.facebook.presto.hive.HiveTestUtils.getProperty;
import static com.facebook.presto.nativeworker.NativeQueryRunnerUtils.createLineitem;
import static com.facebook.presto.nativeworker.PrestoNativeQueryRunnerUtils.REMOTE_FUNCTION_CATALOG_NAME;
import static com.facebook.presto.nativeworker.PrestoNativeQueryRunnerUtils.REMOTE_FUNCTION_JSON_SIGNATURES;
import static com.facebook.presto.nativeworker.PrestoNativeQueryRunnerUtils.setupJsonFunctionNamespaceManager;
import static com.facebook.presto.nativeworker.PrestoNativeQueryRunnerUtils.startRemoteFunctionServer;
@Test(groups = "remote-function")
public abstract class AbstractTestNativeRemoteFunctions
extends AbstractTestQueryFramework
{
// The unix domain socket (UDS) path to communicate with the remote function server.
protected String remoteFunctionServerUds;
// The path to the compiled remote function server binary.
private String remoteFunctionServerBinaryPath;
@BeforeClass
@Override
public void init()
throws Exception
{
preInitQueryRunners();
super.init();
postInitQueryRunners();
}
protected void preInitQueryRunners()
{
// Initialize the remote function thrift server process.
String propertyName = "REMOTE_FUNCTION_SERVER";
remoteFunctionServerBinaryPath = getProperty(propertyName).orElseThrow(() -> new NullPointerException("Remote function server path missing. Add -DREMOTE_FUNCTION_SERVER=<path/to/binary>" +
" to your JVM arguments, or create an environment variable REMOTE_FUNCTION_SERVER with value <path/to/binary>."));
remoteFunctionServerUds = startRemoteFunctionServer(remoteFunctionServerBinaryPath);
}
protected void postInitQueryRunners()
{
// Install json function registration namespace manager.
setupJsonFunctionNamespaceManager(getQueryRunner(), REMOTE_FUNCTION_JSON_SIGNATURES, REMOTE_FUNCTION_CATALOG_NAME);
}
@Override
protected void createTables()
{
// Create some tpch tables.
QueryRunner queryRunner = (QueryRunner) getExpectedQueryRunner();
createLineitem(queryRunner);
}
@Test
public void testRemoteFunction()
{
assertQuery("SELECT remote.schema.ceil(linenumber) FROM lineitem", "SELECT ceil(linenumber) FROM lineitem");
assertQuery("SELECT remote.schema.ceil(discount) FROM lineitem", "SELECT ceil(discount) FROM lineitem");
assertQuery("SELECT remote.schema.ceil(discount * 7) FROM lineitem", "SELECT ceil(discount * 7) FROM lineitem");
assertQuery("SELECT remote.schema.ceil(ceil(discount)) FROM lineitem", "SELECT ceil(ceil(discount * 7)) FROM lineitem");
assertQuery("SELECT remote.schema.concat(returnflag, linestatus) FROM lineitem", "SELECT concat(returnflag, linestatus) FROM lineitem");
assertQuery("SELECT remote.schema.concat('asd', linestatus) FROM lineitem", "SELECT concat('asd', linestatus) FROM lineitem");
// TODO: `throwOnError` needs to be implemented in the server so we can have remote functions as function parameters.
// https://github.com/facebookincubator/velox/issues/5288
//
// "(?s)" enables DOTALL mode so that "." can match newlines.
assertQueryFails("SELECT remote.schema.ceil(remote.schema.ceil(discount)) FROM lineitem", "(?s).*Error.*");
}
}