diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 9f354e4..7a11e9b 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -7,7 +7,7 @@ on: branches: [ "master" ] permissions: - contents: read + contents: write pull-requests: write jobs: @@ -15,25 +15,41 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - - name: Set up JDK 21 - uses: actions/setup-java@v4 - with: - java-version: '21' - distribution: 'temurin' - cache: maven - - - name: Build and Test with Maven - run: mvn -B test - - - name: Add JaCoCo PR Comment - uses: madrapps/jacoco-report@v1.6.1 - if: github.event_name == 'pull_request' - with: - paths: ${{ github.workspace }}/target/site/jacoco/jacoco.xml - token: ${{ secrets.GITHUB_TOKEN }} - min-coverage-overall: 80 - min-coverage-changed-files: 80 - title: 'Code Coverage Report' - update-comment: true \ No newline at end of file + - uses: actions/checkout@v4 + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + java-version: '25' + distribution: 'temurin' + cache: maven + + - name: Build and Test with Maven + run: mvn -B test + + - name: Add JaCoCo PR Comment + uses: madrapps/jacoco-report@v1.6.1 + if: github.event_name == 'pull_request' + with: + paths: ${{ github.workspace }}/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 80 + min-coverage-changed-files: 80 + title: 'Code Coverage Report' + update-comment: true + + - name: Generate JaCoCo Badge + uses: cicirello/jacoco-badge-generator@v2 + if: github.ref == 'refs/heads/master' + with: + badges-directory: .github/badges + generate-branches-badge: true + + - name: Commit and push badge + if: github.ref == 'refs/heads/master' + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add .github/badges + git diff --staged --quiet || git commit -m "chore: update coverage badge [skip ci]" + git push \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6c702be..b0c1566 100644 --- a/pom.xml +++ b/pom.xml @@ -9,8 +9,7 @@ 1.0-SNAPSHOT - 21 - 21 + 25 UTF-8 @@ -44,16 +43,21 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + org.apache.maven.plugins maven-surefire-plugin - 3.2.5 + 3.5.0 org.jacoco jacoco-maven-plugin - 0.8.11 + 0.8.13 @@ -67,6 +71,27 @@ report + + check + test + + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.50 + + + + + + diff --git a/src/test/java/de/asedem/service/CopyServiceTest.java b/src/test/java/de/asedem/service/CopyServiceTest.java new file mode 100644 index 0000000..a7c5c92 --- /dev/null +++ b/src/test/java/de/asedem/service/CopyServiceTest.java @@ -0,0 +1,59 @@ +package de.asedem.service; + +import de.asedem.Ollama; +import de.asedem.exception.OllamaConnectionException; +import de.asedem.rest.HttpMethode; +import de.asedem.rest.Rest; +import de.asedem.rest.RestResponse; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + +class CopyServiceTest { + + @Test + void testMethodCall() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/copy"), + HttpMethode.POST, new CopyService.CopyRequest("llama2:latest", "llama2:copy"))) + .thenReturn(new RestResponse(200, "")); + + assertTrue(ollama.copy("llama2:latest", "llama2:copy")); + } + } + + @Test + void testFalseIfNotSuccessful() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/copy"), + HttpMethode.POST, new CopyService.CopyRequest("llama2:latest", "llama2:copy"))) + .thenReturn(new RestResponse(404, "")); + + assertFalse(ollama.copy("llama2:latest", "llama2:copy")); + } + } + + @Test + void testException() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/copy"), + HttpMethode.POST, new CopyService.CopyRequest("llama2:latest", "llama2:copy"))) + .thenThrow(new IOException()); + + assertThrows(OllamaConnectionException.class, () -> ollama.copy("llama2:latest", "llama2:copy")); + } + } +} diff --git a/src/test/java/de/asedem/service/DeleteServiceTest.java b/src/test/java/de/asedem/service/DeleteServiceTest.java new file mode 100644 index 0000000..3d6399a --- /dev/null +++ b/src/test/java/de/asedem/service/DeleteServiceTest.java @@ -0,0 +1,59 @@ +package de.asedem.service; + +import de.asedem.Ollama; +import de.asedem.exception.OllamaConnectionException; +import de.asedem.rest.HttpMethode; +import de.asedem.rest.Rest; +import de.asedem.rest.RestResponse; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + +class DeleteServiceTest { + + @Test + void testMethodCall() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/delete"), + HttpMethode.POST, new DeleteService.DeleteRequest("llama2:latest"))) + .thenReturn(new RestResponse(200, "")); + + assertTrue(ollama.delete("llama2:latest")); + } + } + + @Test + void testFalseIfNotSuccessful() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/delete"), + HttpMethode.POST, new DeleteService.DeleteRequest("llama2:latest"))) + .thenReturn(new RestResponse(404, "")); + + assertFalse(ollama.delete("llama2:latest")); + } + } + + @Test + void testException() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/delete"), + HttpMethode.POST, new DeleteService.DeleteRequest("llama2:latest"))) + .thenThrow(new IOException()); + + assertThrows(OllamaConnectionException.class, () -> ollama.delete("llama2:latest")); + } + } +} diff --git a/src/test/java/de/asedem/service/ShowInfoServiceTest.java b/src/test/java/de/asedem/service/ShowInfoServiceTest.java new file mode 100644 index 0000000..498942d --- /dev/null +++ b/src/test/java/de/asedem/service/ShowInfoServiceTest.java @@ -0,0 +1,56 @@ +package de.asedem.service; + +import de.asedem.Ollama; +import de.asedem.exception.OllamaConnectionException; +import de.asedem.model.ModelInfo; +import de.asedem.rest.HttpMethode; +import de.asedem.rest.Rest; +import de.asedem.rest.RestResponse; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + +class ShowInfoServiceTest { + + @Test + void testMethodCall() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/show"), HttpMethode.POST, "llama2:latest")) + .thenReturn(new RestResponse(200, """ + { + "license": "MIT", + "modelfile": "# Modelfile", + "parameters": "num_ctx 4096", + "template": "{{ .Prompt }}" + } + """)); + + final ModelInfo modelInfo = ollama.showInfo("llama2:latest"); + + assertEquals("MIT", modelInfo.license()); + assertEquals("# Modelfile", modelInfo.modelFile()); + assertEquals("num_ctx 4096", modelInfo.parameters()); + assertEquals("{{ .Prompt }}", modelInfo.template()); + } + } + + @Test + void testException() { + + final Ollama ollama = Ollama.initDefault(); + + try (MockedStatic utilities = Mockito.mockStatic(Rest.class)) { + utilities.when(() -> Rest.requestSync(ollama.buildUrl("/api/show"), HttpMethode.POST, "llama2:latest")) + .thenThrow(new IOException()); + + assertThrows(OllamaConnectionException.class, () -> ollama.showInfo("llama2:latest")); + } + } +}