Skip to content

Commit

Permalink
Merge pull request #132 from amosproj/Feature/90-add-more-tests
Browse files Browse the repository at this point in the history
Add GradleTaskExecutor tests and fix instability issues with a partner plugin test
  • Loading branch information
lheimbs authored Dec 13, 2023
2 parents 469432a + 5b50219 commit d0349b1
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package io.github.amosproj.pitmutationmate.override.communication

import io.github.amosproj.pitmutationmate.override.communicaiton.UdpMessagingService
import spock.lang.Specification
import spock.lang.Unroll

/**
* UdpMessagingServiceSpec
Expand All @@ -19,7 +18,7 @@ class UdpMessagingServiceSpec extends Specification {

def "Test UDP client sends messages correctly"() {
given:
def port = 50001
def port = findAvailablePort()
def client = new UdpMessagingService(port: port)
def mockServer = new MockUDPServer(port)
mockServer.startServer()
Expand Down Expand Up @@ -50,15 +49,32 @@ Duis eget erat ipsum. V""".trim()
when:
for (message in testMessages) {
client.sendMessage(message)
Thread.sleep(100)
}

then:
Thread.sleep(100)
mockServer.stopServer()
mockServer.thread.join()
for (message in expectedMessages) {
assert mockServer.receivedMessages.contains(message)
}
}

private int findAvailablePort() {
def minPortNumber = 49152
def maxPortNumber = 65535

for (port in minPortNumber..maxPortNumber) {
try {
def socket = new DatagramSocket(port)
socket.close()
return port
} catch (Exception ignored) {
// Port is not available, continue searching
}
}

throw new IllegalStateException("No available port found in the dynamic range")
}

}
7 changes: 5 additions & 2 deletions pitmutationmate/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ dependencies {
implementation("org.pitest:pitest-command-line:1.7.0")
implementation("org.junit.jupiter:junit-jupiter:5.8.1")
implementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
// https://mvnrepository.com/artifact/org.jfree/jfreechart
implementation("org.jfree:jfreechart:1.0.19")
// https://mvnrepository.com/artifact/jfree/jcommon
implementation("org.jfree:jcommon:1.0.24")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0")

// https://mvnrepository.com/artifact/org.mockito/mockito-core
testImplementation("org.mockito:mockito-core:5.8.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
}

group = "com.amos.pitmutationmate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ abstract class BasePitestExecutor {
fun executeTask(
project: Project,
executable: String?,
taskName: String?,
overrideTaskName: String?,
classFQN: String?
): ProcessHandler {
val messagingServer = project.service<UdpMessagingServer>()
messagingServer.startServer(classFQN) // Start the UDP server

val commandLine = buildCommandLine(executable, taskName, project.basePath!!, classFQN, messagingServer.port)
val commandLine = buildCommandLine(executable, overrideTaskName, project.basePath!!, classFQN, messagingServer.port)
log.debug("BasePitestExecutor: executeTask: commandLine: $commandLine")
val processHandler = createProcessHandler(commandLine)
processHandler.addProcessListener(object : ProcessAdapter() {
Expand All @@ -42,7 +42,7 @@ abstract class BasePitestExecutor {

abstract fun buildCommandLine(
executable: String?,
taskName: String?,
overrideTaskName: String?,
projectDir: String,
classFQN: String?,
port: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,47 @@
package com.amos.pitmutationmate.pitmutationmate.execution

import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.openapi.util.SystemInfo
import java.io.File

class GradleTaskExecutor : BasePitestExecutor() {
private var taskName: String = "pitest"
private var gradleExecutable: String? = null
private val windowsGradleExecutable = "gradlew.bat"
private val unixGradleExecutable = "./gradlew"
companion object {
const val PITEST_TASK_NAME = "pitest"
const val WINDOWS_SHELL_EXECUTABLE = "cmd"
const val WINDOWS_FIRST_PARAMETER = "/c"
const val WINDOWS_GRADLE_EXECUTABLE = "gradlew.bat"
const val UNIX_SHELL_EXECUTABLE = "/usr/bin/env"
const val UNIX_FIRST_PARAMETER = "sh"
const val UNIX_GRADLE_EXECUTABLE = "./gradlew"
}
private var systemInfoProvider: SystemInfoProvider = SystemInfo()

override fun buildCommandLine(
executable: String?,
taskName: String?,
overrideTaskName: String?,
projectDir: String,
classFQN: String?,
port: Int
): GeneralCommandLine {
val commandLine = GeneralCommandLine()
var gradleExecutable: String? = executable
var taskName: String? = PITEST_TASK_NAME

this.gradleExecutable = executable
if (!taskName.isNullOrEmpty()) {
this.taskName = taskName!!
if (!overrideTaskName.isNullOrEmpty()) {
taskName = overrideTaskName
}

if (SystemInfo.isWindows) {
if (this.gradleExecutable.isNullOrEmpty()) {
this.gradleExecutable = windowsGradleExecutable
if (systemInfoProvider.isWindows()) {
if (gradleExecutable.isNullOrEmpty()) {
gradleExecutable = WINDOWS_GRADLE_EXECUTABLE
}
commandLine.exePath = "cmd"
commandLine.addParameters("/c", this.gradleExecutable, this.taskName)
commandLine.exePath = WINDOWS_SHELL_EXECUTABLE
commandLine.addParameters(WINDOWS_FIRST_PARAMETER, gradleExecutable, taskName)
} else {
if (this.gradleExecutable.isNullOrEmpty()) {
this.gradleExecutable = unixGradleExecutable
if (gradleExecutable.isNullOrEmpty()) {
gradleExecutable = UNIX_GRADLE_EXECUTABLE
}
commandLine.exePath = "/usr/bin/env"
commandLine.addParameters("sh", this.gradleExecutable, this.taskName)
commandLine.exePath = UNIX_SHELL_EXECUTABLE
commandLine.addParameters(UNIX_FIRST_PARAMETER, gradleExecutable, taskName)
}

commandLine.addParameters(getPitestOverrideParameters(classFQN, port))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class MavenTaskExecutor : BasePitestExecutor() {

override fun buildCommandLine(
executable: String?,
taskName: String?,
overrideTaskName: String?,
projectDir: String,
classFQN: String?,
port: Int
Expand All @@ -23,8 +23,8 @@ class MavenTaskExecutor : BasePitestExecutor() {
this.mavenExecutable = executable!!
}

if (!taskName.isNullOrEmpty()) {
this.taskName = taskName!!
if (!overrideTaskName.isNullOrEmpty()) {
this.taskName = overrideTaskName!!
}

commandLine.exePath = mavenExecutable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2023 Lennart Heimbs

package com.amos.pitmutationmate.pitmutationmate.execution

import com.intellij.openapi.util.SystemInfo

interface SystemInfoProvider {
fun isWindows(): Boolean
}

class SystemInfo : SystemInfoProvider {
override fun isWindows(): Boolean {
return SystemInfo.isWindows
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2023 Lennart Heimbs

package com.amos.pitmutationmate.pitmutationmate.execution

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

/**
* Tests for GradleTaskExecutor
*
* @see GradleTaskExecutor
*/
class GradleTaskExecutorTest {
@Mock
lateinit var systemInfo: SystemInfoProvider // Assuming SystemInfo is a dependency

@InjectMocks
lateinit var gradleTaskExecutor: GradleTaskExecutor

@BeforeEach
fun setup() {
MockitoAnnotations.openMocks(this)
}

@Test
fun `test buildCommandLine for Windows`() {
`when`(systemInfo.isWindows()).thenReturn(true)

val commandLine = gradleTaskExecutor.buildCommandLine(
null,
"clean",
"/path/to/project",
"com.example.Class",
8080
)

assertEquals(GradleTaskExecutor.WINDOWS_SHELL_EXECUTABLE, commandLine.exePath)
assertEquals(GradleTaskExecutor.WINDOWS_FIRST_PARAMETER, commandLine.parametersList.parameters[0])
assertEquals(GradleTaskExecutor.WINDOWS_GRADLE_EXECUTABLE, commandLine.parametersList.parameters[1])
}

@Test
fun `test buildCommandLine for Unix`() {
`when`(systemInfo.isWindows()).thenReturn(false)

val commandLine = gradleTaskExecutor.buildCommandLine(
null,
"clean",
"/path/to/project",
"com.example.Class",
8080
)

assertEquals(GradleTaskExecutor.UNIX_SHELL_EXECUTABLE, commandLine.exePath)
assertEquals(GradleTaskExecutor.UNIX_FIRST_PARAMETER, commandLine.parametersList.parameters[0])
assertEquals(GradleTaskExecutor.UNIX_GRADLE_EXECUTABLE, commandLine.parametersList.parameters[1])
}

@Test
fun `test buildCommandLine without taskName uses default taskName`() {
`when`(systemInfo.isWindows()).thenReturn(true)

val commandLine = gradleTaskExecutor.buildCommandLine(
null,
null,
"/path/to/project",
"com.example.Class",
8080
)

assertEquals(GradleTaskExecutor.PITEST_TASK_NAME, commandLine.parametersList.parameters[2])
}

@Test
fun `test buildCommandLine with taskName uses given taskName`() {
`when`(systemInfo.isWindows()).thenReturn(true)

val taskName = "test123"
val commandLine = gradleTaskExecutor.buildCommandLine(
null,
taskName,
"/path/to/project",
"com.example.Class",
8080
)

assertEquals(taskName, commandLine.parametersList.parameters[2])
}

@Test
fun `test buildCommandLine without classFQDN does not add targetClass override`() {
`when`(systemInfo.isWindows()).thenReturn(true)

val commandLine = gradleTaskExecutor.buildCommandLine(
null,
"clean",
"/path/to/project",
null,
8080
)

for (parameter in commandLine.parametersList.parameters) {
assertFalse(parameter.contains("-Dpitmutationmate.override.targetClasses"))
}
}

@Test
fun `test buildCommandLine with classFQDN adds targetClass override`() {
`when`(systemInfo.isWindows()).thenReturn(true)

val classFQN = "com.example.Class"
val commandLine = gradleTaskExecutor.buildCommandLine(
null,
"clean",
"/path/to/project",
classFQN,
8080
)

assertTrue(
commandLine.parametersList.parameters.contains("-Dpitmutationmate.override.targetClasses=$classFQN")
)
}
}

0 comments on commit d0349b1

Please sign in to comment.