diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AbstractQueryRunnerTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AbstractQueryRunnerTest.java new file mode 100644 index 000000000..d3053af96 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AbstractQueryRunnerTest.java @@ -0,0 +1,117 @@ +/* + * 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.geaflow.analytics.service.client; + +import java.util.concurrent.atomic.AtomicReference; +import org.apache.geaflow.analytics.service.query.QueryResults; +import org.apache.geaflow.common.config.Configuration; +import org.apache.geaflow.common.rpc.HostAndPort; +import org.apache.geaflow.pipeline.service.ServiceType; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class AbstractQueryRunnerTest { + + @Test + public void testQueryRunnerStatusMethods() { + try (TestQueryRunner runner = new TestQueryRunner()) { + QueryRunnerContext context = QueryRunnerContext.newBuilder() + .setConfiguration(new Configuration()) + .setHost(new HostAndPort("localhost", 8080)) + .build(); + + runner.init(context); + + Assert.assertTrue(runner.isRunning()); + Assert.assertFalse(runner.isAborted()); + Assert.assertFalse(runner.isError()); + Assert.assertFalse(runner.isFinished()); + + runner.setStatus(QueryRunnerStatus.ERROR); + Assert.assertFalse(runner.isRunning()); + Assert.assertTrue(runner.isError()); + + runner.setStatus(QueryRunnerStatus.ABORTED); + Assert.assertTrue(runner.isAborted()); + + runner.setStatus(QueryRunnerStatus.FINISHED); + Assert.assertTrue(runner.isFinished()); + } + } + + @Test + public void testInitWithHostAndPort() { + try (TestQueryRunner runner = new TestQueryRunner()) { + Configuration config = new Configuration(); + HostAndPort hostAndPort = new HostAndPort("test-host", 9090); + + QueryRunnerContext context = QueryRunnerContext.newBuilder() + .setConfiguration(config) + .setHost(hostAndPort) + .build(); + + runner.init(context); + + Assert.assertNotNull(runner.getAnalyticsServiceInfo()); + Assert.assertEquals(runner.getAnalyticsServiceInfo().getCoordinatorNum(), 1); + Assert.assertEquals(runner.getAnalyticsServiceInfo().getCoordinatorAddresses(0), hostAndPort); + } + } + + private static class TestQueryRunner extends AbstractQueryRunner { + + @Override + protected void initManagedChannel(HostAndPort address) { + // No-op for test + } + + @Override + public QueryResults executeQuery(String queryScript) { + return null; + } + + @Override + public ServiceType getServiceType() { + return ServiceType.analytics_http; + } + + @Override + public QueryResults cancelQuery(long queryId) { + return null; + } + + @Override + public void close() { + // No-op for test + } + + public void setStatus(QueryRunnerStatus status) { + if (this.queryRunnerStatus == null) { + this.queryRunnerStatus = new AtomicReference<>(status); + } else { + this.queryRunnerStatus.set(status); + } + } + + public AnalyticsServiceInfo getAnalyticsServiceInfo() { + return this.analyticsServiceInfo; + } + } +} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsClientBuilderTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsClientBuilderTest.java new file mode 100644 index 000000000..a3368aba4 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsClientBuilderTest.java @@ -0,0 +1,105 @@ +/* + * 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.geaflow.analytics.service.client; + +import org.apache.geaflow.analytics.service.config.AnalyticsClientConfigKeys; +import org.apache.geaflow.common.config.Configuration; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class AnalyticsClientBuilderTest { + + @Test + public void testBuilderWithHost() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withHost("localhost"); + Assert.assertEquals(builder.getHost(), "localhost"); + } + + @Test + public void testBuilderWithPort() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withPort(8080); + Assert.assertEquals(builder.getPort(), 8080); + } + + @Test + public void testBuilderWithUser() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withUser("testUser"); + Assert.assertEquals(builder.getUser(), "testUser"); + } + + @Test + public void testBuilderWithTimeoutMs() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withTimeoutMs(5000); + Assert.assertEquals( + builder.getConfiguration().getString(AnalyticsClientConfigKeys.ANALYTICS_CLIENT_CONNECT_TIMEOUT_MS), + "5000" + ); + } + + @Test + public void testBuilderWithRetryNum() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withRetryNum(3); + Assert.assertEquals(builder.getQueryRetryNum(), 3); + Assert.assertEquals( + builder.getConfiguration().getString(AnalyticsClientConfigKeys.ANALYTICS_CLIENT_CONNECT_RETRY_NUM), + "3" + ); + } + + @Test + public void testBuilderWithInitChannelPools() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withInitChannelPools(true); + Assert.assertTrue(builder.enableInitChannelPools()); + } + + @Test + public void testBuilderWithConfiguration() { + Configuration config = new Configuration(); + config.put("test.key", "test.value"); + + AnalyticsClientBuilder builder = new AnalyticsClientBuilder(); + builder.withConfiguration(config); + + Assert.assertEquals(builder.getConfiguration().getString("test.key"), "test.value"); + } + + @Test + public void testBuilderChaining() { + AnalyticsClientBuilder builder = new AnalyticsClientBuilder() + .withHost("localhost") + .withPort(8080) + .withUser("testUser") + .withTimeoutMs(5000) + .withRetryNum(3) + .withInitChannelPools(true); + + Assert.assertEquals(builder.getHost(), "localhost"); + Assert.assertEquals(builder.getPort(), 8080); + Assert.assertEquals(builder.getUser(), "testUser"); + Assert.assertEquals(builder.getQueryRetryNum(), 3); + Assert.assertTrue(builder.enableInitChannelPools()); + } +} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsManagerOptionsTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsManagerOptionsTest.java deleted file mode 100644 index ada413518..000000000 --- a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsManagerOptionsTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.geaflow.analytics.service.client; - -import org.testng.Assert; -import org.testng.annotations.Test; - -public class AnalyticsManagerOptionsTest { - private static final String URL_PATH = "/rest/analytics/query/execute"; - - @Test - public void testCreateClientSession() { - String host = "localhost"; - int port = 8080; - AnalyticsManagerSession clientSession1 = AnalyticsManagerOptions.createClientSession(host, port); - AnalyticsManagerSession clientSession2 = AnalyticsManagerOptions.createClientSession(port); - Assert.assertEquals(clientSession1.getServer().toString(), clientSession2.getServer().toString()); - Assert.assertEquals(clientSession1.getServer().toString(), "http://localhost:8080"); - } - - @Test - public void testServerResolve() { - String host = "localhost"; - int port = 8080; - AnalyticsManagerSession clientSession = AnalyticsManagerOptions.createClientSession(host, port); - String fullUri = clientSession.getServer().resolve(URL_PATH).toString(); - Assert.assertEquals(fullUri, "http://localhost:8080/rest/analytics/query/execute"); - } - -} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsServiceInfoTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsServiceInfoTest.java new file mode 100644 index 000000000..3c0a3b4c8 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/AnalyticsServiceInfoTest.java @@ -0,0 +1,86 @@ +/* + * 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.geaflow.analytics.service.client; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.apache.geaflow.common.rpc.HostAndPort; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class AnalyticsServiceInfoTest { + + @Test + public void testAnalyticsServiceInfoWithServerName() { + List addresses = Arrays.asList( + new HostAndPort("host1", 8080), + new HostAndPort("host2", 8081) + ); + + AnalyticsServiceInfo serviceInfo = new AnalyticsServiceInfo("testServer", addresses); + + Assert.assertEquals(serviceInfo.getServerName(), "testServer"); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(), addresses); + Assert.assertEquals(serviceInfo.getCoordinatorNum(), 2); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(0), addresses.get(0)); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(1), addresses.get(1)); + } + + @Test + public void testAnalyticsServiceInfoWithoutServerName() { + List addresses = Collections.singletonList( + new HostAndPort("localhost", 9090) + ); + + AnalyticsServiceInfo serviceInfo = new AnalyticsServiceInfo(addresses); + + Assert.assertNull(serviceInfo.getServerName()); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(), addresses); + Assert.assertEquals(serviceInfo.getCoordinatorNum(), 1); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(0), addresses.get(0)); + } + + @Test + public void testGetCoordinatorAddressByIndex() { + List addresses = Arrays.asList( + new HostAndPort("host1", 8080), + new HostAndPort("host2", 8081), + new HostAndPort("host3", 8082) + ); + + AnalyticsServiceInfo serviceInfo = new AnalyticsServiceInfo(addresses); + + Assert.assertEquals(serviceInfo.getCoordinatorNum(), 3); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(0).getHost(), "host1"); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(0).getPort(), 8080); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(1).getHost(), "host2"); + Assert.assertEquals(serviceInfo.getCoordinatorAddresses(2).getHost(), "host3"); + } + + @Test + public void testEmptyCoordinatorAddresses() { + List addresses = Collections.emptyList(); + AnalyticsServiceInfo serviceInfo = new AnalyticsServiceInfo(addresses); + + Assert.assertEquals(serviceInfo.getCoordinatorNum(), 0); + Assert.assertTrue(serviceInfo.getCoordinatorAddresses().isEmpty()); + } +} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/HttpResponseTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/HttpResponseTest.java new file mode 100644 index 000000000..3d0644d61 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/HttpResponseTest.java @@ -0,0 +1,181 @@ +/* + * 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.geaflow.analytics.service.client; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import org.apache.geaflow.analytics.service.query.QueryError; +import org.apache.geaflow.analytics.service.query.QueryResults; +import org.apache.geaflow.common.exception.GeaflowRuntimeException; +import org.apache.geaflow.common.serialize.SerializerFactory; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class HttpResponseTest { + + @Test + public void testSuccessfulResponse() throws IOException { + QueryError queryError = new QueryError("success", 0); + QueryResults queryResults = new QueryResults("query-1", queryError); + byte[] serializedData = SerializerFactory.getKryoSerializer().serialize(queryResults); + + CloseableHttpClient mockClient = Mockito.mock(CloseableHttpClient.class); + CloseableHttpResponse mockResponse = Mockito.mock(CloseableHttpResponse.class); + StatusLine mockStatusLine = Mockito.mock(StatusLine.class); + HttpEntity mockEntity = Mockito.mock(HttpEntity.class); + + Mockito.when(mockClient.execute(Mockito.any(HttpPost.class))).thenReturn(mockResponse); + Mockito.when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); + Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); + Mockito.when(mockStatusLine.toString()).thenReturn("HTTP/1.1 200 OK"); + Mockito.when(mockResponse.getAllHeaders()).thenReturn(new org.apache.http.Header[0]); + Mockito.when(mockResponse.getEntity()).thenReturn(mockEntity); + Mockito.when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(serializedData)); + + HttpPost request = new HttpPost("http://localhost:8080/test"); + HttpResponse httpResponse = HttpResponse.execute(mockClient, request); + + Assert.assertTrue(httpResponse.enableQuerySuccess()); + Assert.assertEquals(httpResponse.getStatusCode(), HttpStatus.SC_OK); + Assert.assertNotNull(httpResponse.getValue()); + Assert.assertEquals(httpResponse.getValue().getQueryId(), "query-1"); + } + + @Test + public void testFailedResponse() throws IOException { + byte[] errorData = "Internal Server Error".getBytes(); + + CloseableHttpClient mockClient = Mockito.mock(CloseableHttpClient.class); + CloseableHttpResponse mockResponse = Mockito.mock(CloseableHttpResponse.class); + StatusLine mockStatusLine = Mockito.mock(StatusLine.class); + HttpEntity mockEntity = Mockito.mock(HttpEntity.class); + + Mockito.when(mockClient.execute(Mockito.any(HttpPost.class))).thenReturn(mockResponse); + Mockito.when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); + Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); + Mockito.when(mockStatusLine.toString()).thenReturn("HTTP/1.1 500 Internal Server Error"); + Mockito.when(mockResponse.getAllHeaders()).thenReturn(new org.apache.http.Header[0]); + Mockito.when(mockResponse.getEntity()).thenReturn(mockEntity); + Mockito.when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(errorData)); + + HttpPost request = new HttpPost("http://localhost:8080/test"); + HttpResponse httpResponse = HttpResponse.execute(mockClient, request); + + Assert.assertFalse(httpResponse.enableQuerySuccess()); + Assert.assertEquals(httpResponse.getStatusCode(), HttpStatus.SC_INTERNAL_SERVER_ERROR); + Assert.assertNotNull(httpResponse.getException()); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testGetValueOnFailedResponse() throws IOException { + byte[] errorData = "Error".getBytes(); + + CloseableHttpClient mockClient = Mockito.mock(CloseableHttpClient.class); + CloseableHttpResponse mockResponse = Mockito.mock(CloseableHttpResponse.class); + StatusLine mockStatusLine = Mockito.mock(StatusLine.class); + HttpEntity mockEntity = Mockito.mock(HttpEntity.class); + + Mockito.when(mockClient.execute(Mockito.any(HttpPost.class))).thenReturn(mockResponse); + Mockito.when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); + Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_BAD_REQUEST); + Mockito.when(mockStatusLine.toString()).thenReturn("HTTP/1.1 400 Bad Request"); + Mockito.when(mockResponse.getAllHeaders()).thenReturn(new org.apache.http.Header[0]); + Mockito.when(mockResponse.getEntity()).thenReturn(mockEntity); + Mockito.when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(errorData)); + + HttpPost request = new HttpPost("http://localhost:8080/test"); + HttpResponse httpResponse = HttpResponse.execute(mockClient, request); + + httpResponse.getValue(); // Should throw exception + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testExecuteWithIOException() throws IOException { + CloseableHttpClient mockClient = Mockito.mock(CloseableHttpClient.class); + Mockito.when(mockClient.execute(Mockito.any(HttpPost.class))) + .thenThrow(new IOException("Connection refused")); + + HttpPost request = new HttpPost("http://localhost:8080/test"); + HttpResponse.execute(mockClient, request); + } + + @Test + public void testGetHeaders() throws IOException { + QueryError queryError = new QueryError("success", 0); + QueryResults queryResults = new QueryResults("query-1", queryError); + byte[] serializedData = SerializerFactory.getKryoSerializer().serialize(queryResults); + + CloseableHttpClient mockClient = Mockito.mock(CloseableHttpClient.class); + CloseableHttpResponse mockResponse = Mockito.mock(CloseableHttpResponse.class); + StatusLine mockStatusLine = Mockito.mock(StatusLine.class); + HttpEntity mockEntity = Mockito.mock(HttpEntity.class); + + org.apache.http.Header[] headers = new org.apache.http.Header[0]; + + Mockito.when(mockClient.execute(Mockito.any(HttpPost.class))).thenReturn(mockResponse); + Mockito.when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); + Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); + Mockito.when(mockStatusLine.toString()).thenReturn("HTTP/1.1 200 OK"); + Mockito.when(mockResponse.getAllHeaders()).thenReturn(headers); + Mockito.when(mockResponse.getEntity()).thenReturn(mockEntity); + Mockito.when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(serializedData)); + + HttpPost request = new HttpPost("http://localhost:8080/test"); + HttpResponse httpResponse = HttpResponse.execute(mockClient, request); + + Assert.assertNotNull(httpResponse.getHeaders()); + Assert.assertEquals(httpResponse.getHeaders().length, 0); + } + + @Test + public void testToString() throws IOException { + QueryError queryError = new QueryError("success", 0); + QueryResults queryResults = new QueryResults("query-1", queryError); + byte[] serializedData = SerializerFactory.getKryoSerializer().serialize(queryResults); + + CloseableHttpClient mockClient = Mockito.mock(CloseableHttpClient.class); + CloseableHttpResponse mockResponse = Mockito.mock(CloseableHttpResponse.class); + StatusLine mockStatusLine = Mockito.mock(StatusLine.class); + HttpEntity mockEntity = Mockito.mock(HttpEntity.class); + + Mockito.when(mockClient.execute(Mockito.any(HttpPost.class))).thenReturn(mockResponse); + Mockito.when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); + Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); + Mockito.when(mockStatusLine.toString()).thenReturn("HTTP/1.1 200 OK"); + Mockito.when(mockResponse.getAllHeaders()).thenReturn(new org.apache.http.Header[0]); + Mockito.when(mockResponse.getEntity()).thenReturn(mockEntity); + Mockito.when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(serializedData)); + + HttpPost request = new HttpPost("http://localhost:8080/test"); + HttpResponse httpResponse = HttpResponse.execute(mockClient, request); + + String toString = httpResponse.toString(); + Assert.assertNotNull(toString); + Assert.assertTrue(toString.contains("statusCode")); + Assert.assertTrue(toString.contains("querySuccess")); + } +} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/QueryRunnerContextTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/QueryRunnerContextTest.java new file mode 100644 index 000000000..ad724eff0 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/QueryRunnerContextTest.java @@ -0,0 +1,82 @@ +/* + * 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.geaflow.analytics.service.client; + +import org.apache.geaflow.common.config.Configuration; +import org.apache.geaflow.common.rpc.HostAndPort; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class QueryRunnerContextTest { + + @Test + public void testQueryRunnerContextBuilder() { + Configuration config = new Configuration(); + config.put("test.key", "test.value"); + HostAndPort hostAndPort = new HostAndPort("localhost", 8080); + + QueryRunnerContext context = QueryRunnerContext.newBuilder() + .setConfiguration(config) + .setHost(hostAndPort) + .enableInitChannelPools(true) + .setAnalyticsServiceJobName("testJob") + .setMetaServerAddress("meta-server:8081") + .build(); + + Assert.assertNotNull(context.getConfiguration()); + Assert.assertEquals(context.getConfiguration().getString("test.key"), "test.value"); + Assert.assertEquals(context.getHostAndPort(), hostAndPort); + Assert.assertTrue(context.isInitChannelPools()); + Assert.assertTrue(context.enableInitChannelPools()); + Assert.assertEquals(context.getMetaServerBaseNode(), "testJob"); + Assert.assertEquals(context.getMetaServerAddress(), "meta-server:8081"); + } + + @Test + public void testQueryRunnerContextBuilderWithMinimalParams() { + Configuration config = new Configuration(); + + QueryRunnerContext context = QueryRunnerContext.newBuilder() + .setConfiguration(config) + .build(); + + Assert.assertNotNull(context.getConfiguration()); + Assert.assertNull(context.getHostAndPort()); + Assert.assertFalse(context.isInitChannelPools()); + Assert.assertNull(context.getMetaServerBaseNode()); + Assert.assertNull(context.getMetaServerAddress()); + } + + @Test + public void testQueryRunnerContextBuilderChaining() { + Configuration config = new Configuration(); + HostAndPort hostAndPort = new HostAndPort("host", 9090); + + QueryRunnerContext.ClientHandlerContextBuilder builder = QueryRunnerContext.newBuilder(); + QueryRunnerContext context = builder + .setConfiguration(config) + .setHost(hostAndPort) + .enableInitChannelPools(false) + .build(); + + Assert.assertNotNull(context); + Assert.assertFalse(context.isInitChannelPools()); + } +} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/QueryRunnerStatusTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/QueryRunnerStatusTest.java new file mode 100644 index 000000000..f9c7578d5 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/QueryRunnerStatusTest.java @@ -0,0 +1,49 @@ +/* + * 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.geaflow.analytics.service.client; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class QueryRunnerStatusTest { + + @Test + public void testQueryRunnerStatusValues() { + QueryRunnerStatus[] statuses = QueryRunnerStatus.values(); + Assert.assertEquals(statuses.length, 4); + Assert.assertEquals(statuses[0], QueryRunnerStatus.RUNNING); + Assert.assertEquals(statuses[1], QueryRunnerStatus.ERROR); + Assert.assertEquals(statuses[2], QueryRunnerStatus.ABORTED); + Assert.assertEquals(statuses[3], QueryRunnerStatus.FINISHED); + } + + @Test + public void testQueryRunnerStatusValueOf() { + Assert.assertEquals(QueryRunnerStatus.valueOf("RUNNING"), QueryRunnerStatus.RUNNING); + Assert.assertEquals(QueryRunnerStatus.valueOf("ERROR"), QueryRunnerStatus.ERROR); + Assert.assertEquals(QueryRunnerStatus.valueOf("ABORTED"), QueryRunnerStatus.ABORTED); + Assert.assertEquals(QueryRunnerStatus.valueOf("FINISHED"), QueryRunnerStatus.FINISHED); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testQueryRunnerStatusInvalidValueOf() { + QueryRunnerStatus.valueOf("INVALID"); + } +} diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/jdbc/AnalyticsDriverURITest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/jdbc/AnalyticsDriverURITest.java index 9cb4a7be9..986413aea 100644 --- a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/jdbc/AnalyticsDriverURITest.java +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/jdbc/AnalyticsDriverURITest.java @@ -19,35 +19,192 @@ package org.apache.geaflow.analytics.service.client.jdbc; -import static java.lang.String.format; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.fail; - +import java.net.URI; +import java.util.Map; import java.util.Properties; +import org.apache.geaflow.common.exception.GeaflowRuntimeException; +import org.testng.Assert; import org.testng.annotations.Test; public class AnalyticsDriverURITest { @Test - public void testInvalidURI() { - assertInvalid("jdbc:geaflow://localhost/", "No port number specified:"); + public void testValidURLWithUserAndGraphView() { + String url = "jdbc:geaflow://localhost:8080/myGraph?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + + Assert.assertEquals(driverURI.getGraphView(), "myGraph"); + Assert.assertEquals(driverURI.getUser(), "testUser"); + Assert.assertEquals(driverURI.getAuthority(), "localhost:8080"); + Assert.assertFalse(driverURI.isCompressionDisabled()); + } + + @Test + public void testValidURLWithoutGraphView() { + String url = "jdbc:geaflow://localhost:8080?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + + Assert.assertNull(driverURI.getGraphView()); + Assert.assertEquals(driverURI.getUser(), "testUser"); + } + + @Test + public void testUserInProperties() { + String url = "jdbc:geaflow://localhost:8080"; + Properties props = new Properties(); + props.setProperty("user", "propUser"); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + + Assert.assertEquals(driverURI.getUser(), "propUser"); + } + + @Test + public void testURLParametersParsing() { + String url = "jdbc:geaflow://localhost:8080?user=testUser&timeout=5000"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + + Properties properties = driverURI.getProperties(); + Assert.assertEquals(properties.getProperty("user"), "testUser"); + Assert.assertEquals(properties.getProperty("timeout"), "5000"); + } + + @Test + public void testHttpURI() { + String url = "jdbc:geaflow://localhost:8080?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + URI httpUri = driverURI.getHttpUri(); + + Assert.assertEquals(httpUri.getScheme(), "http"); + Assert.assertEquals(httpUri.getHost(), "localhost"); + Assert.assertEquals(httpUri.getPort(), 8080); + } + + @Test + public void testSecureHttpURI() { + String url = "jdbc:geaflow://localhost:443?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + URI httpUri = driverURI.getHttpUri(); + + Assert.assertEquals(httpUri.getScheme(), "https"); + Assert.assertEquals(httpUri.getPort(), 443); + } + + @Test + public void testGetSessionProperties() { + String url = "jdbc:geaflow://localhost:8080?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + Map sessionProps = driverURI.getSessionProperties(); + + Assert.assertNotNull(sessionProps); + } + + @Test + public void testGetCustomHeaders() { + String url = "jdbc:geaflow://localhost:8080?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + Map customHeaders = driverURI.getCustomHeaders(); + + Assert.assertNotNull(customHeaders); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testInvalidURLWithoutHost() { + String url = "jdbc:geaflow://:8080?user=testUser"; + Properties props = new Properties(); + + new AnalyticsDriverURI(url, props); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testInvalidURLWithoutPort() { + String url = "jdbc:geaflow://localhost?user=testUser"; + Properties props = new Properties(); + + new AnalyticsDriverURI(url, props); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testInvalidURLWithInvalidPort() { + String url = "jdbc:geaflow://localhost:99999?user=testUser"; + Properties props = new Properties(); + + new AnalyticsDriverURI(url, props); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testInvalidURLWithZeroPort() { + String url = "jdbc:geaflow://localhost:0?user=testUser"; + Properties props = new Properties(); + + new AnalyticsDriverURI(url, props); } - private static void assertInvalid(String url, String prefix) { - try { - createDriverUri(url); - fail("expected exception"); - } catch (Exception e) { - assertNotNull(e.getMessage()); - if (!e.getMessage().startsWith(prefix)) { - fail(format("expected:<%s> to start with <%s>", e.getMessage(), prefix)); - } - } + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testURLWithoutUser() { + String url = "jdbc:geaflow://localhost:8080"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + driverURI.getUser(); // Should throw exception } - private static AnalyticsDriverURI createDriverUri(String url) { - Properties properties = new Properties(); - properties.setProperty("user", "only-test"); - return new AnalyticsDriverURI(url, properties); + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testDuplicatePropertyInURLAndProperties() { + String url = "jdbc:geaflow://localhost:8080?user=urlUser"; + Properties props = new Properties(); + props.setProperty("user", "propUser"); + + new AnalyticsDriverURI(url, props); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testDuplicateParameterInURL() { + String url = "jdbc:geaflow://localhost:8080?user=user1&user=user2"; + Properties props = new Properties(); + + new AnalyticsDriverURI(url, props); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testInvalidGraphViewPath() { + String url = "jdbc:geaflow://localhost:8080/graph/extra/segment?user=testUser"; + Properties props = new Properties(); + + new AnalyticsDriverURI(url, props); + } + + @Test + public void testEmptyGraphView() { + String url = "jdbc:geaflow://localhost:8080/?user=testUser"; + Properties props = new Properties(); + + // Empty path after '/' is treated as no graph view, which is valid + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + Assert.assertNull(driverURI.getGraphView()); + } + + @Test + public void testGraphViewWithTrailingSlash() { + String url = "jdbc:geaflow://localhost:8080/myGraph/?user=testUser"; + Properties props = new Properties(); + + AnalyticsDriverURI driverURI = new AnalyticsDriverURI(url, props); + + Assert.assertEquals(driverURI.getGraphView(), "myGraph"); } } diff --git a/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/utils/JDBCUtilsTest.java b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/utils/JDBCUtilsTest.java new file mode 100644 index 000000000..e8bb27b98 --- /dev/null +++ b/geaflow/geaflow-analytics-service/geaflow-analytics-service-client/src/test/java/org/apache/geaflow/analytics/service/client/utils/JDBCUtilsTest.java @@ -0,0 +1,67 @@ +/* + * 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.geaflow.analytics.service.client.utils; + +import org.apache.geaflow.common.exception.GeaflowRuntimeException; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class JDBCUtilsTest { + + @Test + public void testAcceptsValidURL() { + String validUrl = "jdbc:geaflow://localhost:8080"; + Assert.assertTrue(JDBCUtils.acceptsURL(validUrl)); + } + + @Test + public void testAcceptsValidURLWithPath() { + String validUrl = "jdbc:geaflow://localhost:8080/graphView"; + Assert.assertTrue(JDBCUtils.acceptsURL(validUrl)); + } + + @Test + public void testAcceptsValidURLWithParameters() { + String validUrl = "jdbc:geaflow://localhost:8080?user=test&password=test123"; + Assert.assertTrue(JDBCUtils.acceptsURL(validUrl)); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testRejectsInvalidURL() { + String invalidUrl = "jdbc:mysql://localhost:3306/test"; + JDBCUtils.acceptsURL(invalidUrl); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testRejectsEmptyURL() { + JDBCUtils.acceptsURL(""); + } + + @Test(expectedExceptions = GeaflowRuntimeException.class) + public void testRejectsNonJDBCURL() { + String nonJdbcUrl = "http://localhost:8080"; + JDBCUtils.acceptsURL(nonJdbcUrl); + } + + @Test + public void testDriverURLStartConstant() { + Assert.assertEquals(JDBCUtils.DRIVER_URL_START, "jdbc:geaflow://"); + } +}