/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2015
*/
package com.ibm.streamsx.topology.test.splpy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.logging.Logger;
import org.junit.Test;
import com.ibm.streamsx.topology.internal.process.ProcessOutputToLogger;
import com.ibm.streamsx.topology.test.TestTopology;
public class PythonExtractTest extends TestTopology {
static Logger trace = Logger.getLogger(PythonExtractTest.class.getName());
public static int extract(File tkDir, boolean tkMake) throws Exception {
String topoTk = System.getProperty("topology.toolkit.release");
String streams = System.getProperty("topology.install.compile");
File expy = new File(topoTk, "bin/spl-python-extract.py");
List<String> commands = new ArrayList<String>();
commands.add(System.getProperty("topology.test.python", "python3"));
commands.add(expy.getAbsolutePath());
commands.add("--directory");
commands.add(tkDir.getAbsolutePath());
if (tkMake)
commands.add("--make-toolkit");
ProcessBuilder pb = new ProcessBuilder(commands);
// Set STREAMS_INSTALL in case it was overriden for compilation
pb.environment().put("STREAMS_INSTALL", streams);
Process exProcess = pb.start();
ProcessOutputToLogger.log(trace, exProcess);
exProcess.getOutputStream().close();
int rc = exProcess.waitFor();
trace.info("spl-python-extract.py complete: return code=" + rc);
return rc;
}
public static File createPyTk(String namespace, List<String> pythonCode) throws Exception {
File tkdir = Files.createTempDirectory("testpyex").toFile();
File pystreams = new File(tkdir, "opt/python/streams");
pystreams.mkdirs();
if (namespace != null || pythonCode != null) {
Path python = Files.createTempFile(pystreams.toPath(), "tpx", ".py");
Files.write(python, Collections.singletonList("from streamsx.spl import spl\n"), StandardCharsets.UTF_8);
if (namespace != null) {
List<String> nsfn = new ArrayList<>();
nsfn.add("def splNamespace():");
nsfn.add(" return '" + namespace + "'\n");
Files.write(python, nsfn, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
}
if (pythonCode != null)
Files.write(python, pythonCode, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
}
return tkdir;
}
@Test
public void testEmptyToolkit() throws Exception {
_testEmptyToolkit(false);
}
@Test
public void testEmptyToolkitMake() throws Exception {
_testEmptyToolkit(true);
}
private void _testEmptyToolkit(boolean make) throws Exception {
File tkdir = Files.createTempDirectory("testpyex").toFile();
try {
assertEquals(0, extract(tkdir, make));
// Ensure running the extract doesn't cause issues
// for subsequent executions.
assertEquals(0, extract(tkdir, make));
} finally {
tkdir.delete();
}
}
@Test
public void testEmptyToolkitDir() throws Exception {
_testEmptyToolkitWithDir(false);
}
@Test
public void testEmptyToolkitDirMake() throws Exception {
_testEmptyToolkitWithDir(true);
}
static final String NS = "testpy.extract";
private void _testEmptyToolkitWithDir(boolean make) throws Exception {
File tkdir = createPyTk(null, null);
try {
assertEquals(0, extract(tkdir, make));
// Ensure running the extract doesn't cause issues
// for subsequent executions.
assertEquals(0, extract(tkdir, make));
} finally {
tkdir.delete();
}
}
@Test
public void testEmptyPython() throws Exception {
_testToolkit(Collections.emptyList(), false, tkdir->{});
}
@Test
public void testEmptyPythonMake() throws Exception {
_testToolkit(Collections.emptyList(), true, tkdir->{});
}
public static class TestGeneratedOpArtifacts implements Consumer<File> {
private final String op;
private final boolean pm;
public TestGeneratedOpArtifacts(String op) {
this.op = op;
this.pm = false;
}
public TestGeneratedOpArtifacts(String op, boolean pm) {
this.op = op;
this.pm = pm;
}
@Override
public void accept(File tkdir) {
assertTrue(tkdir.isDirectory());
assertTrue(tkdir.exists());
File nsdir = new File(tkdir, NS);
assertTrue(nsdir.isDirectory());
assertTrue(nsdir.exists());
File opdir = new File(nsdir, op);
assertTrue(opdir.isDirectory());
assertTrue(opdir.exists());
File opFile = new File(opdir, op + ".xml");
assertTrue(opFile.toString(), opFile.isFile());
assertTrue(opFile.toString(), opFile.exists());
opFile = new File(opdir, op + "_cpp.cgt");
assertTrue(opFile.toString(), opFile.isFile());
assertTrue(opFile.toString(), opFile.exists());
opFile = new File(opdir, op + "_h.cgt");
assertTrue(opFile.toString(), opFile.isFile());
assertTrue(opFile.toString(), opFile.exists());
if (pm) {
opFile = new File(opdir, op + "_cpp.pm");
assertTrue(opFile.toString(), opFile.isFile());
assertTrue(opFile.toString(), opFile.exists());
opFile = new File(opdir, op + "_h.pm");
assertTrue(opFile.toString(), opFile.isFile());
assertTrue(opFile.toString(), opFile.exists());
}
}
}
@Test
public void testPythonMap() throws Exception {
String[] code = {
"@spl.map()\n",
"def f1(*tuple):\n",
" pass\n"
};
_testToolkit(Arrays.asList(code), false, new TestGeneratedOpArtifacts("f1"));
}
@Test
public void testPythonMapMake() throws Exception {
String[] code = {
"@spl.map()\n",
"def f2(*tuple):\n",
" pass\n"
};
_testToolkit(Arrays.asList(code), true, new TestGeneratedOpArtifacts("f2", true));
}
public static void _testToolkit(List<String> lines, boolean make, Consumer<File> tester) throws Exception {
File tkdir = createPyTk(NS, lines);
try {
assertEquals(0, extract(tkdir, make));
tester.accept(tkdir);
// Ensure running the extract doesn't cause issues
// for subsequent executions.
assertEquals(0, extract(tkdir, make));
} finally {
tkdir.delete();
}
}
}