>From Ian Maxon <[email protected]>:

Ian Maxon has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21961?usp=email )


Change subject: [ASTERIXDB-3933][API] Return 501 for UDF GET iff cloud mode
......................................................................

[ASTERIXDB-3933][API] Return 501 for UDF GET iff cloud mode

Details:
 - Cloud mode means database-level organization. The current
   library listing code for GET doesn't work for that.
   Until it does, we shouldn't attempt to list what we know
   will not be organized as the method expects

Generated-by: Claude Opus 5.5
Change-Id: I4003de47c906f84bce686cadb6fc8c021da136a0
---
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfDSApiServlet.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/CloudUDFLibrarian.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/IExternalUDFLibrarian.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonAzureTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonGCSTest.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonS3Test.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonCloudQueries.xml
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonLibraryApiQueries.xml
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.0.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.1.lib.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.2.lib.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.3.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/py_library_list/py_library_list.1.regexjson
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python.xml
A 
asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_cloud.xml
M 
asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_fenced.xml
M 
asterixdb/asterix-podman/src/test/java/org/apache/asterix/test/podman/PodmanUDFLibrarian.java
20 files changed, 276 insertions(+), 16 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/61/21961/1

diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
index 64dddc0..768df64 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
@@ -376,7 +376,7 @@
     protected void get(IServletRequest request, IServletResponse response) 
throws Exception {
         String localPath = localPath(request);
         try {
-            if (localPath.equals("/") || localPath.equals("")) {
+            if (isLibraryListingRequest(request)) {
                 //TODO: nicer way to get this into display form?
                 Map<Namespace, Map<String, String>> dvToLibHashes =
                         
ExternalLibraryUtils.produceLibraryListing(libraryManager);
@@ -420,6 +420,11 @@
         }
     }

+    protected boolean isLibraryListingRequest(IServletRequest request) {
+        String localPath = localPath(request);
+        return localPath.equals("/") || localPath.isEmpty();
+    }
+
     protected void writeException(Exception e, IServletResponse response) {
         response.setStatus(toHttpErrorStatus(e));
         PrintWriter responseWriter = response.writer();
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfDSApiServlet.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfDSApiServlet.java
index 9381cb9..1f5decf 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfDSApiServlet.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfDSApiServlet.java
@@ -47,6 +47,7 @@
 import org.apache.hyracks.http.api.IServletResponse;

 import io.netty.buffer.ByteBufInputStream;
+import io.netty.handler.codec.http.HttpResponseStatus;

 public class NCUdfDSApiServlet extends AbstractNCUdfServlet {

@@ -102,6 +103,13 @@
     }

     @Override
+    protected void get(IServletRequest request, IServletResponse response) 
throws Exception {
+        // TODO: the listing does not reflect the libraries installed in cloud 
storage; refuse it until it does
+        //       any other path in GET is irrelevant in cloud mode
+        sendError(response, HttpResponseStatus.NOT_IMPLEMENTED);
+    }
+
+    @Override
     protected void post(IServletRequest request, IServletResponse response) 
throws IOException {
         if (isRequestPermitted(request, response)) {
             handleModification(request, response, LibraryOperation.UPSERT);
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/CloudUDFLibrarian.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/CloudUDFLibrarian.java
index 853c380..11ae0f4 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/CloudUDFLibrarian.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/CloudUDFLibrarian.java
@@ -83,11 +83,19 @@
         hc.delete().uri(path).responseSingle((response, content) -> 
handleResponse(response, content)).block();
     }

-    private Mono<Void> handleResponse(HttpClientResponse response, 
reactor.netty.ByteBufMono content) {
+    @Override
+    public String list(String path, Pair<String, String> credentials) {
+        UnixDomainSocketAddress sockAddr = 
UnixDomainSocketAddress.of(sockPath);
+        HttpClient hc = HttpClient.create().runOn(elg)
+                .headers(h -> h.set("Authorization", 
createAuthHeader(credentials))).remoteAddress(() -> sockAddr);
+        return hc.get().uri(path).responseSingle((response, content) -> 
handleResponse(response, content)).block();
+    }
+
+    private Mono<String> handleResponse(HttpClientResponse response, 
reactor.netty.ByteBufMono content) {
         return content.asString().defaultIfEmpty("").flatMap(body -> {
             int respCode = response.status().code();
             if (respCode == HttpResponseStatus.OK.code()) {
-                return Mono.empty();
+                return Mono.just(body);
             }

             String errorMessage;
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
index 5b92d7d..fd1d370 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
+import java.nio.charset.StandardCharsets;

 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.commons.lang3.tuple.Pair;
@@ -32,6 +33,7 @@
 import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.protocol.HttpClientContext;
 import org.apache.http.client.utils.URIUtils;
@@ -42,6 +44,7 @@
 import org.apache.http.impl.client.BasicAuthCache;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;

 import com.fasterxml.jackson.databind.ObjectMapper;

@@ -77,6 +80,16 @@
         handleResponse(response);
     }

+    @Override
+    public String list(String path, Pair<String, String> credentials) throws 
IOException, AsterixException {
+        HttpClientContext hcCtx = createHttpClientContext(URI.create(path), 
credentials);
+        HttpResponse response = hc.execute(new HttpGet(path), hcCtx);
+        if (response.getStatusLine().getStatusCode() != 200) {
+            handleResponse(response);
+        }
+        return EntityUtils.toString(response.getEntity(), 
StandardCharsets.UTF_8);
+    }
+
     private HttpClientContext createHttpClientContext(URI path, Pair<String, 
String> credentials) {
         HttpClientContext hcCtx = HttpClientContext.create();
         HttpHost h = URIUtils.extractHost(path);
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/IExternalUDFLibrarian.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/IExternalUDFLibrarian.java
index 49f0b15..4e2fb8e 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/IExternalUDFLibrarian.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/IExternalUDFLibrarian.java
@@ -33,5 +33,11 @@

     void uninstall(String path, Pair<String, String> credentials) throws 
IOException, AsterixException;

+    /**
+     * @return the body of a successful GET of the library listing at {@code 
path}
+     * @throws AsterixException if the listing is refused
+     */
+    String list(String path, Pair<String, String> credentials) throws 
Exception;
+
     SocketType getSocketType();
 }
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonAzureTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonAzureTest.java
index e0f7c61..cb7fe44 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonAzureTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonAzureTest.java
@@ -68,7 +68,7 @@
 public class CloudPythonAzureTest {

     private final TestCaseContext tcCtx;
-    private static final String SUITE_TESTS = "testsuite_it_python.xml";
+    private static final String SUITE_TESTS = "testsuite_it_python_cloud.xml";
     private static final String ONLY_TESTS = 
"testsuite_cloud_storage_only.xml";
     private static final String DELTA_RESULT_PATH = "results_cloud";
     public static final String CONFIG_FILE_TEMPLATE = 
"src/test/resources/cc-cloud-storage-azblob.ftl";
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonGCSTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonGCSTest.java
index 46f67e2..ae42077 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonGCSTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonGCSTest.java
@@ -64,7 +64,7 @@
 public class CloudPythonGCSTest {

     private final TestCaseContext tcCtx;
-    private static final String SUITE_TESTS = "testsuite_it_python.xml";
+    private static final String SUITE_TESTS = "testsuite_it_python_cloud.xml";
     private static final String ONLY_TESTS = 
"testsuite_cloud_storage_only.xml";
     private static final String DELTA_RESULT_PATH = "results_cloud";
     private static final String CONFIG_FILE_NAME = 
"src/test/resources/cc-cloud-storage-gcs-python.conf";
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonS3Test.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonS3Test.java
index ed51726..5e72a6f 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonS3Test.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudPythonS3Test.java
@@ -59,7 +59,7 @@
     private static final Logger LOGGER = LogManager.getLogger();

     private final TestCaseContext tcCtx;
-    private static final String SUITE_TESTS = "testsuite_it_python.xml";
+    private static final String SUITE_TESTS = "testsuite_it_python_cloud.xml";
     private static final String ONLY_TESTS = 
"testsuite_cloud_storage_only.xml";
     private static final String DELTA_RESULT_PATH = "results_cloud";
     public static final String CONFIG_FILE_TEMPLATE = 
"src/test/resources/cc-cloud-storage.conf.ftl";
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index 46698bc..b55c6f2 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -192,6 +192,7 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectReader;
 import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.databind.util.RawValue;

@@ -217,6 +218,7 @@
     protected static final ObjectReader RESULT_NODE_READER =
             
JSON_NODE_READER.with(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
     protected static final String SQLPP = "sqlpp";
+    private static final String LIBRARY_API_PATH = "/admin/udf";
     private static final String DEFAULT_PLAN_FORMAT = "string";
     // see
     // 
https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/417184
@@ -1500,19 +1502,21 @@
                 lines = stripAllComments(statement).trim().split("\n");
                 for (String line : lines) {
                     String[] command = line.trim().split(" ");
-                    //TODO: this is not right. URLEncoder does not properly 
encode paths.
-                    String dataverse = URLEncoder.encode(command[1], 
StandardCharsets.US_ASCII.name());
-                    String library = URLEncoder.encode(command[2], 
StandardCharsets.US_ASCII.name());
-                    String basePath = "/admin/udf/" + dataverse + "/" + 
library;
-                    String path = "";
-                    switch (librarian.getSocketType()){
-                        case DOMAIN -> path = basePath;
-                        case LOOPBACK -> path = 
createEndpointURI(basePath).toString();
-                        default -> path = 
createEndpointURI(basePath).toString();
-                    }
                     if (command.length < 2) {
                         throw new Exception("invalid library command: " + 
line);
                     }
+                    if (command[0].equals("list")) {
+                        if (command.length != 4) {
+                            throw new Exception("invalid library format");
+                        }
+                        listLibraries(command[1], Pair.of(command[2], 
command[3]), testCaseCtx, cUnit, testFile,
+                                statement, queryCount, expectedResultFileCtxs, 
actualPath);
+                        continue;
+                    }
+                    //TODO: this is not right. URLEncoder does not properly 
encode paths.
+                    String dataverse = URLEncoder.encode(command[1], 
StandardCharsets.US_ASCII.name());
+                    String library = URLEncoder.encode(command[2], 
StandardCharsets.US_ASCII.name());
+                    String path = libraryEndpoint(LIBRARY_API_PATH + "/" + 
dataverse + "/" + library);
                     switch (command[0]) {
                         case "install":
                             if (command.length != 7) {
@@ -1691,6 +1695,38 @@
         queryCount.increment();
     }

+    private String libraryEndpoint(String path) throws URISyntaxException {
+        return librarian.getSocketType() == 
IExternalUDFLibrarian.SocketType.DOMAIN ? path
+                : createEndpointURI(path).toString();
+    }
+
+    /**
+     * Writes the libraries the library API lists for {@code dataverse} as the 
next result of the test. The listing
+     * is narrowed to one dataverse so that libraries left installed by other 
tests do not leak into the result.
+     */
+    private void listLibraries(String dataverse, Pair<String, String> 
credentials, TestCaseContext testCaseCtx,
+            CompilationUnit cUnit, File testFile, String statement, MutableInt 
queryCount,
+            List<TestFileContext> expectedResultFileCtxs, String actualPath) 
throws Exception {
+        String listing = librarian.list(libraryEndpoint(LIBRARY_API_PATH), 
credentials);
+        ArrayNode libraries = OM.createArrayNode();
+        for (JsonNode library : OM.readTree(listing)) {
+            if (dataverse.equals(library.get("dataverse").asText())) {
+                libraries.add(library);
+            }
+        }
+        String result = OM.writeValueAsString(libraries);
+        File expectedResultFile = queryCount.intValue() < 
expectedResultFileCtxs.size()
+                ? expectedResultFileCtxs.get(queryCount.intValue()).getFile() 
: null;
+        File actualResultFile = expectedResultFile == null ? null
+                : testCaseCtx.getActualResultFile(cUnit, expectedResultFile, 
new File(actualPath));
+        if (actualResultFile != null) {
+            writeOutputToFile(actualResultFile, result);
+        }
+        matchExpectedResult(testFile, expectedResultFile, actualResultFile, 
IOUtils.toInputStream(result, UTF_8),
+                queryCount, expectedResultFileCtxs.size(), 
cUnit.getOutputDir().getCompare(), statement);
+        queryCount.increment();
+    }
+
     private void matchExpectedResult(File testFile, File expectedResultFile, 
File actualResultFile,
             InputStream resultStream, MutableInt queryCount, int 
numResultFiles, ComparisonEnum compare,
             String statement) throws Exception {
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonCloudQueries.xml
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonCloudQueries.xml
new file mode 100644
index 0000000..a73cc1e
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonCloudQueries.xml
@@ -0,0 +1,27 @@
+<!--
+  ~  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.
+  ~
+  -->
+<test-group name="external-library-python-cloud">
+  <test-case FilePath="external-library">
+    <compilation-unit name="py_library_list">
+      <output-dir compare="Text">py_library_list</output-dir>
+      <expected-error>501 Not Implemented</expected-error>
+    </compilation-unit>
+  </test-case>
+</test-group>
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonLibraryApiQueries.xml
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonLibraryApiQueries.xml
new file mode 100644
index 0000000..934ed6f
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/PythonLibraryApiQueries.xml
@@ -0,0 +1,26 @@
+<!--
+  ~  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.
+  ~
+  -->
+<test-group name="external-library-python-library-api">
+  <test-case FilePath="external-library">
+    <compilation-unit name="py_library_list">
+      <output-dir compare="Text">py_library_list</output-dir>
+    </compilation-unit>
+  </test-case>
+</test-group>
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.0.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.0.ddl.sqlpp
new file mode 100644
index 0000000..b190601
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.0.ddl.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+drop  dataverse pylistlib if exists;
+create  dataverse pylistlib;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.1.lib.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.1.lib.sqlpp
new file mode 100644
index 0000000..78650d8
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.1.lib.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+install pylistlib testlib python admin admin target/TweetSent.pyz
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.2.lib.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.2.lib.sqlpp
new file mode 100644
index 0000000..f8902cd
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.2.lib.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+list pylistlib admin admin
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.3.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.3.ddl.sqlpp
new file mode 100644
index 0000000..e48864c
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/py_library_list/py_library_list.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop  dataverse pylistlib;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/py_library_list/py_library_list.1.regexjson
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/py_library_list/py_library_list.1.regexjson
new file mode 100644
index 0000000..75e8a57
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/py_library_list/py_library_list.1.regexjson
@@ -0,0 +1,5 @@
+[{
+       "dataverse": "pylistlib",
+       "hash_md5": "R{[a-zA-Z0-9-]+}",
+       "name": "testlib"
+}]
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python.xml 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python.xml
index ef0b605..2a0bdb8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python.xml
@@ -19,6 +19,7 @@
   -->
 <!DOCTYPE test-suite [
         <!ENTITY PythonQueries SYSTEM 
"queries_sqlpp/external-library/PythonQueries.xml">
+        <!ENTITY PythonLibraryApiQueries SYSTEM 
"queries_sqlpp/external-library/PythonLibraryApiQueries.xml">
         ]>
 <test-suite
              xmlns="urn:xml.testframework.asterix.apache.org"
@@ -26,4 +27,5 @@
              QueryOffsetPath="queries_sqlpp"
              QueryFileExtension=".sqlpp">
   &PythonQueries;
+  &PythonLibraryApiQueries;
 </test-suite>
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_cloud.xml
 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_cloud.xml
new file mode 100644
index 0000000..9283cf8
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_cloud.xml
@@ -0,0 +1,33 @@
+<!--
+  ~  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.
+  ~
+  -->
+<!-- Everything in PythonQueries.xml, plus the cases whose outcome differs 
when the UDF API is served in a
+     cloud deployment. -->
+<!DOCTYPE test-suite [
+        <!ENTITY PythonQueries SYSTEM 
"queries_sqlpp/external-library/PythonQueries.xml">
+        <!ENTITY PythonCloudQueries SYSTEM 
"queries_sqlpp/external-library/PythonCloudQueries.xml">
+        ]>
+<test-suite
+             xmlns="urn:xml.testframework.asterix.apache.org"
+             ResultOffsetPath="results"
+             QueryOffsetPath="queries_sqlpp"
+             QueryFileExtension=".sqlpp">
+  &PythonQueries;
+  &PythonCloudQueries;
+</test-suite>
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_fenced.xml
 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_fenced.xml
index 6b02f65..08eee74 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_fenced.xml
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_python_fenced.xml
@@ -23,6 +23,7 @@
      PodmanPythonFunctionIT reads this file. -->
 <!DOCTYPE test-suite [
         <!ENTITY PythonQueries SYSTEM 
"queries_sqlpp/external-library/PythonQueries.xml">
+        <!ENTITY PythonLibraryApiQueries SYSTEM 
"queries_sqlpp/external-library/PythonLibraryApiQueries.xml">
         <!ENTITY PythonFencedQueries SYSTEM 
"queries_sqlpp/external-library/PythonFencedQueries.xml">
         ]>
 <test-suite
@@ -31,5 +32,6 @@
              QueryOffsetPath="queries_sqlpp"
              QueryFileExtension=".sqlpp">
   &PythonQueries;
+  &PythonLibraryApiQueries;
   &PythonFencedQueries;
 </test-suite>
diff --git 
a/asterixdb/asterix-podman/src/test/java/org/apache/asterix/test/podman/PodmanUDFLibrarian.java
 
b/asterixdb/asterix-podman/src/test/java/org/apache/asterix/test/podman/PodmanUDFLibrarian.java
index 32968c2..a9ee971 100644
--- 
a/asterixdb/asterix-podman/src/test/java/org/apache/asterix/test/podman/PodmanUDFLibrarian.java
+++ 
b/asterixdb/asterix-podman/src/test/java/org/apache/asterix/test/podman/PodmanUDFLibrarian.java
@@ -72,6 +72,14 @@
     }

     @Override
+    public String list(String path, Pair<String, String> credentials) throws 
Exception {
+        Container.ExecResult curlResult = asterix.execInContainer("curl", 
"--no-progress-meter", "-u",
+                credentials.getLeft() + ":" + credentials.getRight(), 
"http://localhost:19004"; + path);
+        handleResponse(curlResult);
+        return curlResult.getStdout();
+    }
+
+    @Override
     public SocketType getSocketType() {
         // install()/uninstall() build their own "http://localhost:19004"; + 
path URL for curl to run
         // inside the container, so TestExecutor must hand us the bare path, 
not a fully-qualified URI.

--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21961?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://asterix-gerrit.ics.uci.edu/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I4003de47c906f84bce686cadb6fc8c021da136a0
Gerrit-Change-Number: 21961
Gerrit-PatchSet: 1
Gerrit-Owner: Ian Maxon <[email protected]>

Reply via email to