Skip to content

Commit

Permalink
Enable testing platform conditions
Browse files Browse the repository at this point in the history
- Implement unit tests for the ByteBuddy platform conditions
- Extract the ByteBuddy platform conditions to a separate utility class
  to enable unit testing them separately. This also enables adding additional
  checks in the future without making the InlineDelegateByteBuddyMockMaker
  much more complicated.
- Added dependency at test time for junit-jupiter-params to enable writing
  parameterized unit tests.
  • Loading branch information
ascopes committed Oct 24, 2023
1 parent d8cb1ef commit 16dd5cf
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 11 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Expand Up @@ -96,6 +96,8 @@ dependencies {
implementation libraries.objenesis

testImplementation libraries.assertj
testImplementation libraries.junitJupiterApi
testImplementation libraries.junitJupiterParams

testUtil sourceSets.test.output

Expand Down
1 change: 1 addition & 0 deletions gradle/dependencies.gradle
Expand Up @@ -10,6 +10,7 @@ versions.errorprone = '2.23.0'

libraries.junit4 = 'junit:junit:4.13.2'
libraries.junitJupiterApi = "org.junit.jupiter:junit-jupiter-api:${versions.junitJupiter}"
libraries.junitJupiterParams = "org.junit.jupiter:junit-jupiter-params:${versions.junitJupiter}"
libraries.junitPlatformLauncher = 'org.junit.platform:junit-platform-launcher:1.10.0'
libraries.junitJupiterEngine = "org.junit.jupiter:junit-jupiter-engine:${versions.junitJupiter}"
libraries.junitVintageEngine = "org.junit.vintage:junit-vintage-engine:${versions.junitJupiter}"
Expand Down
Expand Up @@ -207,17 +207,7 @@ class InlineDelegateByteBuddyMockMaker
InlineDelegateByteBuddyMockMaker() {
if (INITIALIZATION_ERROR != null) {
String detail;

boolean isNativeAndroid = System.getProperty("java.specification.vendor", "")
.toLowerCase()
.contains("android");

// Termux can run any JVM, such as Oracle, but may still fail to instrument the
// JVM correctly, so it is worth detecting this as well.
boolean isTermuxAndroid = System.getProperty("java.home", "")
.contains("/com.termux/");

if (isNativeAndroid || isTermuxAndroid) {
if (PlatformUtils.isAndroidPlatform() || PlatformUtils.isProbablyTermuxEnvironment()) {
detail =
"It appears as if you are trying to run this mock maker on Android which does not support the instrumentation API.";
} else {
Expand Down
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.creation.bytebuddy;

/**
* Helpers for various platform detection mechanisms related to the ByteBuddy mock maker.
*
* @author Ashley Scopes
*/
final class PlatformUtils {
private PlatformUtils() {
// Static-only class.
}

static boolean isAndroidPlatform() {
return System.getProperty("java.specification.vendor", "")
.toLowerCase()
.contains("android");
}

static boolean isProbablyTermuxEnvironment() {
boolean isLinux = System.getProperty("os.name", "").equalsIgnoreCase("linux");
boolean isInTermuxData =
System.getProperty("java.home", "").toLowerCase().contains("/com.termux/");
return isLinux && isInTermuxData;
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2023 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.creation.bytebuddy;

import java.util.Properties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.parallel.Isolated;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.assertj.core.api.Assertions.assertThat;

/**
* @author Ashley Scopes
*/
@Isolated("modifies system properties temporarily")
class PlatformUtilsTest {
Properties globalProperties;

@BeforeEach
void setUp() {
globalProperties = new Properties();
globalProperties.putAll(System.getProperties());
System.getProperties().clear();
}

@AfterEach
void tearDown() {
System.getProperties().clear();
System.getProperties().putAll(globalProperties);
}

@CsvSource({
" android, true",
" AnDrOId, true",
"anythingElse, false",
" , false",
})
@ParameterizedTest
void isAndroidPlatform_returns_expected_value(String vendor, boolean expectedResult) {
// Given
setProperty("java.specification.vendor", vendor);

// Then
assertThat(PlatformUtils.isAndroidPlatform()).isEqualTo(expectedResult);
}

@CsvSource({
" linux, /data/data/com.termux/whatever, true",
" linux, /foo/bar/com.termux/somedir, true",
" LINUX, /data/data/com.termux/whatever, true",
" Linux, /foo/bar/com.termux/somedir, true",
"Mac OS X 13.0, /foo/bar/com.termux/somedir, false",
" Windows 10, /foo/bar/com.termux/somedir, false",
" OS/2, /foo/bar/com.termux/somedir, false",
" Linux, /usr/share/java, false",
" , , false",
" foo, , false",
" , foo, false",
" linux, , false",
" , /data/data/com.termux/whatever, false",
})
@ParameterizedTest
void isAndroidPlatform_returns_expected_value(
String os, String javaHome, boolean expectedResult) {
// Given
setProperty("os.name", os);
setProperty("java.home", javaHome);

assertThat(PlatformUtils.isAndroidPlatform()).isEqualTo(expectedResult);
}

static void setProperty(String name, String value) {
if (value == null) {
System.clearProperty(name);
} else {
System.setProperty(name, value);
}
}
}

0 comments on commit 16dd5cf

Please sign in to comment.