blob: 0eee2153054976ed7c04e5f3eb8f8b1b38377584 [file] [log] [blame]
/*
* 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.servicecomb.foundation.common.utils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.jar.JarFile;
import org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;
import org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({JvmUtils.class})
@PowerMockIgnore("jdk.internal.reflect.*")
public class TestJvmUtils {
static String orgCmd = System.getProperty(JvmUtils.SUN_JAVA_COMMAND);
@Before
public void setup() {
System.clearProperty(JvmUtils.SUN_JAVA_COMMAND);
}
@AfterClass
public static void tearDown() {
if (orgCmd == null) {
System.clearProperty(JvmUtils.SUN_JAVA_COMMAND);
return;
}
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, orgCmd);
}
@Test
public void findMainClass_notExist() {
Assertions.assertNull(JvmUtils.findMainClass());
}
@Test
public void findMainClass_existButEmpty() {
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, "");
Assertions.assertNull(JvmUtils.findMainClass());
}
@Test
public void findMainClass_invalid() {
LogCollector logCollector = new LogCollector();
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, "invalidCls");
Assertions.assertNull(JvmUtils.findMainClass());
Assertions.assertEquals("\"invalidCls\" is not a valid class.", logCollector.getEvents().get(0).getMessage());
logCollector.teardown();
}
@Test
public void findMainClass_class_normal() {
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, TestJvmUtils.class.getName() + " arg");
Assertions.assertEquals(TestJvmUtils.class, JvmUtils.findMainClass());
}
@Test
public void findMainClass_jar_normal() throws Exception {
URL url = PowerMockito.mock(URL.class);
String command = "a.jar";
String manifestUri = "jar:file:" + new File(command).getAbsolutePath() + "!/" + JarFile.MANIFEST_NAME;
PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
.withArguments(manifestUri).thenReturn(url);
String content = String.format("Manifest-Version: 1.0\nMain-Class: %s\n", TestJvmUtils.class.getName());
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
PowerMockito.when(url.openStream()).thenAnswer(invocation -> inputStream);
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + " arg");
Assertions.assertEquals(TestJvmUtils.class, JvmUtils.findMainClass());
}
@Test
public void findMainClass_jar_null() throws Exception {
String content = "Manifest-Version: 1.0\n";
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
URL url = PowerMockito.mock(URL.class);
String command = "a.jar";
String manifestUri = "jar:file:/" + new File(command).getAbsolutePath() + "!/" + JarFile.MANIFEST_NAME;
PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
.withArguments(manifestUri).thenAnswer(invocation -> url);
PowerMockito.when(url.openStream()).thenAnswer(invocation -> inputStream);
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + " arg");
Assertions.assertNull(JvmUtils.findMainClass());
}
@Test
public void findMainClass_jar_readFailed() throws Exception {
URL url = PowerMockito.mock(URL.class);
String command = "a.jar";
String manifestUri = "jar:file:" + new File(command).getAbsolutePath() + "!/" + JarFile.MANIFEST_NAME;
PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
.withArguments(manifestUri).thenReturn(url);
PowerMockito.when(url.openStream()).thenThrow(new RuntimeExceptionWithoutStackTrace());
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + " arg");
Assertions.assertNull(JvmUtils.findMainClass());
}
@Test
public void findMainClassByStackTrace_normal() throws Exception{
RuntimeException re = PowerMockito.mock(RuntimeException.class);
PowerMockito.when(re.getStackTrace()).thenReturn(new StackTraceElement[]{
new StackTraceElement("declaring.class.fileName", "methodName", "fileName", 100),
new StackTraceElement("java.lang.String", "main", "fileName", 120)
});
PowerMockito.whenNew(RuntimeException.class).withNoArguments().thenReturn(re);
Assertions.assertEquals(String.class, JvmUtils.findMainClassByStackTrace());
}
@Test
public void findMainClassByStackTrace_invalidClass() throws Exception{
RuntimeException re = PowerMockito.mock(RuntimeException.class);
PowerMockito.when(re.getStackTrace()).thenReturn(new StackTraceElement[]{
new StackTraceElement("declaring.class.fileName", "methodName", "fileName", 100),
new StackTraceElement("InvalidClass", "main", "fileName", 120)
});
PowerMockito.whenNew(RuntimeException.class).withNoArguments().thenReturn(re);
Assertions.assertNull(JvmUtils.findMainClassByStackTrace());
}
@Test
public void findMainClassByStackTrace_withoutMainMethod() throws Exception{
RuntimeException re = PowerMockito.mock(RuntimeException.class);
PowerMockito.when(re.getStackTrace()).thenReturn(new StackTraceElement[]{
new StackTraceElement("declaring.class.fileName", "methodName", "fileName", 100),
new StackTraceElement("InvalidClass", "methodName", "fileName", 120)
});
PowerMockito.whenNew(RuntimeException.class).withNoArguments().thenReturn(re);
Assertions.assertNull(JvmUtils.findMainClassByStackTrace());
}
@Test
public void findMainClassByStackTrace_emptyStackTrace() throws Exception{
RuntimeException re = PowerMockito.mock(RuntimeException.class);
PowerMockito.when(re.getStackTrace()).thenReturn(new StackTraceElement[]{});
PowerMockito.whenNew(RuntimeException.class).withNoArguments().thenReturn(re);
Assertions.assertNull(JvmUtils.findMainClassByStackTrace());
}
@Test
public void findMainClassByStackTrace_nullStackTrace() throws Exception{
RuntimeException re = PowerMockito.mock(RuntimeException.class);
PowerMockito.when(re.getStackTrace()).thenReturn(null);
PowerMockito.whenNew(RuntimeException.class).withNoArguments().thenReturn(re);
Assertions.assertNull(JvmUtils.findMainClassByStackTrace());
}
}