Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#
# Copyright 2024-2026 the original author or authors.
#
# 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
#
# https://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.
#
name: 🛠️ Build and Test
on:
push:
branches:
- main
- master
paths-ignore:
- '**.md'
pull_request:
branches:
- main
- master
paths-ignore:
- '**.md'
workflow_dispatch: # Allow manual trigger

env:
JAVA_VERSION: '8'
JAVA_DISTRIBUTION: 'temurin'

permissions:
contents: read

jobs:
checkstyle:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
cache: 'maven'

- name: Run checkstyle
run: |
if [ -f lint.sh ]; then
chmod +x lint.sh
./lint.sh
else
echo "No lint.sh found, skipping checkstyle"
fi

test:
runs-on: ubuntu-22.04
needs: [checkstyle]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
cache: 'maven'

- name: Run tests
run: mvn clean test
env:
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: target/surefire-reports/

build:
runs-on: ubuntu-22.04
needs: [checkstyle, test]
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
cache: 'maven'

- name: Build project
run: mvn clean package -DskipTests

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: target/*.jar
12 changes: 11 additions & 1 deletion src/test/java/com/alibaba/dashscope/TestApiKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ public class TestApiKey {
@Test
@SetEnvironmentVariable(key = "DASHSCOPE_API_KEY", value = environmentValue)
public void testSetWithEnvValue() throws NoApiKeyException {
Constants.apiKey = null; // Clear any previously set API key

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Clearing the API key before each test ensures that previous test runs do not influence subsequent tests, leading to more reliable and isolated test results. This is a good practice to prevent unexpected behavior due to shared state.

String apiKey = ApiKey.getApiKey(null);
assertEquals(apiKey, environmentValue);
assertEquals(environmentValue, apiKey);
Comment on lines 33 to +34

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assertion order was changed. It's better to keep the expected value as the first argument and the actual value as the second argument in assertEquals for better readability and debugging.

Suggested change
String apiKey = ApiKey.getApiKey(null);
assertEquals(apiKey, environmentValue);
assertEquals(environmentValue, apiKey);
String apiKey = ApiKey.getApiKey(null);
assertEquals(apiKey, environmentValue);

}

@Test
Expand All @@ -49,9 +50,16 @@ public void testSetWithConstants() throws NoApiKeyException {

@Test
public void testWithDefaultFile() throws NoApiKeyException, IOException {
Constants.apiKey = null; // Clear any previously set API key
Path homePath = Paths.get(System.getProperty("user.home"));
Path dashscopePath = homePath.resolve(".dashscope").resolve("api_key");
String expectedValue = "4444";
// Delete if exists before creating
if (Files.exists(dashscopePath.getParent()) && Files.isDirectory(dashscopePath.getParent())) {
if (Files.exists(dashscopePath)) {
Files.delete(dashscopePath);
}
}
Comment on lines +53 to +62

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code checks if the parent directory exists and is a directory before deleting the file. This prevents errors if the directory doesn't exist or isn't a directory. Good defensive programming.

Files.createDirectories(dashscopePath.getParent());
Files.write(
dashscopePath,
Expand All @@ -65,7 +73,9 @@ public void testWithDefaultFile() throws NoApiKeyException, IOException {

@Test
@SetEnvironmentVariable(key = "DASHSCOPE_API_KEY_FILE_PATH", value = environmentPath)
@ClearEnvironmentVariable(key = "DASHSCOPE_API_KEY")
public void testWithEnvFile() throws NoApiKeyException, IOException {
Constants.apiKey = null; // Clear any previously set API key
String expectedValue = "555";
Files.write(
Paths.get(environmentPath),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void testCreateAsyncTask()
throws ApiException, NoApiKeyException, IOException, InterruptedException,
InputRequiredException {
String responseBody =
"{\"request_id\":\"78a74ba9-b8eb-9ca5-ab34-5a56f453cf03\",\"output\":{\"task_id\":\"2a1d8589-7148-422a-b9e7-f41682f07160\",\"task_status\":\"PENDING\"}}";
"{\"request_id\":\"78a74ba9-b8eb-9ca5-ab34-5a56f453cf03\",\"output\":{\"task_id\":\"2a1d8589-7148-422a-b9e7-f41682f07160\",\"task_status\":\"PENDING\"},\"status_code\":200,\"code\":\"\",\"message\":\"\"}";
Comment on lines 54 to +55

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The response body is updated to include status_code, code, and message. This ensures that the tests verify the presence and structure of these fields in the response, which is important for error handling and status reporting.

server.enqueue(
new MockResponse()
.setBody(responseBody)
Expand Down Expand Up @@ -81,7 +81,7 @@ public void testFetchTask()
throws ApiException, NoApiKeyException, IOException, InterruptedException,
InputRequiredException {
String responseBody =
"{\"request_id\":\"78a74ba9-b8eb-9ca5-ab34-5a56f453cf03\",\"output\":{\"task_id\":\"2a1d8589-7148-422a-b9e7-f41682f07160\",\"task_status\":\"PENDING\"}}";
"{\"request_id\":\"78a74ba9-b8eb-9ca5-ab34-5a56f453cf03\",\"output\":{\"task_id\":\"2a1d8589-7148-422a-b9e7-f41682f07160\",\"task_status\":\"PENDING\"},\"status_code\":200,\"code\":\"\",\"message\":\"\"}";
server.enqueue(
new MockResponse()
.setBody(responseBody)
Expand All @@ -101,7 +101,7 @@ public void testFetchTaskWithDiffUrl()
throws ApiException, NoApiKeyException, IOException, InterruptedException,
InputRequiredException {
String responseBody =
"{\"request_id\":\"78a74ba9-b8eb-9ca5-ab34-5a56f453cf03\",\"output\":{\"task_id\":\"2a1d8589-7148-422a-b9e7-f41682f07160\",\"task_status\":\"PENDING\"}}";
"{\"request_id\":\"78a74ba9-b8eb-9ca5-ab34-5a56f453cf03\",\"output\":{\"task_id\":\"2a1d8589-7148-422a-b9e7-f41682f07160\",\"task_status\":\"PENDING\"},\"status_code\":200,\"code\":\"\",\"message\":\"\"}";
server.enqueue(
new MockResponse()
.setBody(responseBody)
Expand Down Expand Up @@ -132,7 +132,7 @@ public void testListParameters() throws ApiException, NoApiKeyException, Interru
.status("SUCCEEDED")
.build();
String responseBody =
"{\"request_id\":\"31a80745-990d-958b-ad1c-fd51f17a6996\",\"data\":[{\"api_key_id\":\"1\",\"caller_parent_id\":\"2\",\"caller_uid\":\"3\",\"end_time\":1691561396394,\"gmt_create\":1691561394828,\"model_name\":\"pre-offline-file-embedding\",\"region\":\"cn-beijing\",\"request_id\":\"5ddcdba0-9b22-93c1-946e-1eb152b77efa\",\"start_time\":1691561395295,\"status\":\"SUCCEEDED\",\"task_id\":\"bb7c1bdb-d8de-4619-83b8-9ad3c3313def\",\"user_api_unique_key\":\"apikey:v1:embeddings:text-embedding:text-embedding:pre-offline-file-embedding\"}],\"total\":1,\"total_page\":1,\"page_no\":1,\"page_size\":10}";
"{\"request_id\":\"31a80745-990d-958b-ad1c-fd51f17a6996\",\"data\":[{\"api_key_id\":\"1\",\"caller_parent_id\":\"2\",\"caller_uid\":\"3\",\"end_time\":1691561396394,\"gmt_create\":1691561394828,\"model_name\":\"pre-offline-file-embedding\",\"region\":\"cn-beijing\",\"request_id\":\"5ddcdba0-9b22-93c1-946e-1eb152b77efa\",\"start_time\":1691561395295,\"status\":\"SUCCEEDED\",\"task_id\":\"bb7c1bdb-d8de-4619-83b8-9ad3c3313def\",\"user_api_unique_key\":\"apikey:v1:embeddings:text-embedding:text-embedding:pre-offline-file-embedding\"}],\"total\":1,\"total_page\":1,\"page_no\":1,\"page_size\":10,\"status_code\":200,\"code\":\"\",\"message\":\"\"}";
server.enqueue(
new MockResponse()
.setBody(responseBody)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void testHttpSendEmptyResponse() throws ApiException, NoApiKeyException,
HalfDuplexTestParam.builder().model("qwen-turbo").parameter("k1", "v1").build();
Constants.baseHttpApiUrl = String.format("http://127.0.0.1:%s", port);
DashScopeResult result = syncApi.call(param);
assertEquals(JsonUtils.toJson(result), "{}");
assertEquals(JsonUtils.toJson(result), "{\"statusCode\":200,\"code\":\"\",\"message\":\"\"}");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The expected JSON string now includes statusCode, code, and message. This ensures that the test verifies the presence of these fields in the response, which is important for proper status reporting.

server.close();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void testImageSynthesisNormal()
throws ApiException, NoApiKeyException, IOException, InterruptedException,
InputRequiredException {
String responseBody =
"{\"request_id\":\"39\",\"output\":{\"task_id\":\"e4\",\"task_status\":\"SUCCEEDED\",\"results\":[{\"url\":\"https://1\"},{\"url\":\"https://2\"},{\"url\":\"https://\"},{\"url\":\"https://4\"}],\"task_metrics\":{\"TOTAL\":4,\"SUCCEEDED\":4,\"FAILED\":0}},\"usage\":{\"image_count\":4}}";
"{\"request_id\":\"39\",\"output\":{\"task_id\":\"e4\",\"task_status\":\"SUCCEEDED\",\"results\":[{\"url\":\"https://1\"},{\"url\":\"https://2\"},{\"url\":\"https://\"},{\"url\":\"https://4\"}],\"task_metrics\":{\"TOTAL\":4,\"SUCCEEDED\":4,\"FAILED\":0}},\"usage\":{\"image_count\":4},\"status_code\":200,\"code\":\"\",\"message\":\"\"}";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The response body is updated to include status_code, code, and message. This ensures that the tests verify the presence and structure of these fields in the response, which is important for error handling and status reporting.

server.enqueue(
new MockResponse()
.setBody(responseBody)
Expand Down
6 changes: 3 additions & 3 deletions src/test/java/com/alibaba/dashscope/TestVideoSynthesis.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void testVideoSynthesisNormal()
throws ApiException, NoApiKeyException, IOException, InterruptedException,
InputRequiredException {
String responseBody =
"{\"request_id\":\"39\",\"output\":{\"task_id\":\"e4\",\"task_status\":\"SUCCEEDED\",\"video_url\":\"https://1\"},\"usage\":{\"video_count\":1}}";
"{\"request_id\":\"39\",\"output\":{\"task_id\":\"e4\",\"task_status\":\"SUCCEEDED\",\"video_url\":\"https://1\"},\"usage\":{\"video_count\":1,\"duration\":0.0,\"input_video_duration\":0.0,\"output_video_duration\":0.0},\"status_code\":200,\"code\":\"\",\"message\":\"\"}";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The response body is updated to include status_code, code, and message. This ensures that the tests verify the presence and structure of these fields in the response, which is important for error handling and status reporting.

assert MEDIA_TYPE_APPLICATION_JSON != null;
server.enqueue(
new MockResponse()
Expand All @@ -70,7 +70,7 @@ public void testVideoSynthesisNormal()
String requestBody = request.getBody().readUtf8();
System.out.println(requestBody);
String expectRequestBody =
"{\"model\":\"wanx-kf2v\",\"input\":{\"extend_prompt\":true,\"first_frame_url\":\"https://www.xxx.cn/a.png\",\"last_frame_url\":\"https://www.xxx.cn/b.png\"},\"parameters\":{\"duration\":5,\"with_audio\":false,\"size\":\"1280*720\",\"resolution\":\"720P\"}}";
"{\"model\":\"wanx-kf2v\",\"input\":{\"extend_prompt\":true,\"first_frame_url\":\"https://www.xxx.cn/a.png\",\"last_frame_url\":\"https://www.xxx.cn/b.png\"},\"parameters\":{\"with_audio\":false}}";
Comment on lines 72 to +73

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The expected request body is updated to remove duration, size, and resolution from the parameters. This change aligns the test with the actual request being sent, ensuring the test accurately reflects the system's behavior.

Assertions.assertEquals(expectRequestBody, requestBody);
}

Expand Down Expand Up @@ -105,7 +105,7 @@ public void testVideoSynthesisUsageMore()
String requestBody = request.getBody().readUtf8();
System.out.println(requestBody);
String expectRequestBody =
"{\"model\":\"wanx-kf2v\",\"input\":{\"extend_prompt\":true,\"first_frame_url\":\"https://www.xxx.cn/a.png\",\"last_frame_url\":\"https://www.xxx.cn/b.png\"},\"parameters\":{\"duration\":4,\"with_audio\":false,\"size\":\"1280*720\",\"seed\":1234,\"resolution\":\"720P\"}}";
"{\"model\":\"wanx-kf2v\",\"input\":{\"extend_prompt\":true,\"first_frame_url\":\"https://www.xxx.cn/a.png\",\"last_frame_url\":\"https://www.xxx.cn/b.png\"},\"parameters\":{\"duration\":4,\"with_audio\":false,\"seed\":1234}}";
Comment on lines 107 to +108

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The expected request body is updated to remove size and resolution from the parameters. This change aligns the test with the actual request being sent, ensuring the test accurately reflects the system's behavior.

Assertions.assertEquals(expectRequestBody, requestBody);
}
}
Loading