diff --git a/USAGE_DATA.md b/USAGE_DATA.md new file mode 100644 index 000000000..532398eed --- /dev/null +++ b/USAGE_DATA.md @@ -0,0 +1,18 @@ +# Telemetry data collection + +If `xml.telemetry.enabled` is set to `true`, LemMinX emits telemetry events. +These events can be collected by the LSP client program. + +When telemetry events are enabled, the following information is emitted when the language server starts: + + * JVM information: + * Whether LemMinX is being run with Java or as a GraalVM native image (binary) + * The name of the vm (`java.vm.name`) + * The name of the runtime (`java.runtime.name`) + * The version of the JVM (`java.version`) + * The free, total, and max VM memory + * Version information: + * The server version number + * Note: Does NOT include the `JAVA_HOME` environment variable for privacy reasons + +Currently, the startup event is the only telemetry event that is emitted. diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/XMLLanguageServer.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/XMLLanguageServer.java index 3c410ae6d..97915ac1b 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/XMLLanguageServer.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/XMLLanguageServer.java @@ -45,6 +45,7 @@ import org.eclipse.lemminx.settings.InitializationOptionsSettings; import org.eclipse.lemminx.settings.ServerSettings; import org.eclipse.lemminx.settings.SharedSettings; +import org.eclipse.lemminx.settings.XMLTelemetrySettings; import org.eclipse.lemminx.settings.XMLCodeLensSettings; import org.eclipse.lemminx.settings.XMLCompletionSettings; import org.eclipse.lemminx.settings.XMLFormattingOptions; @@ -54,8 +55,9 @@ import org.eclipse.lemminx.settings.capabilities.InitializationOptionsExtendedClientCapabilities; import org.eclipse.lemminx.settings.capabilities.ServerCapabilitiesInitializer; import org.eclipse.lemminx.settings.capabilities.XMLCapabilityManager; +import org.eclipse.lemminx.telemetry.TelemetryManager; import org.eclipse.lemminx.utils.FilesUtils; -import org.eclipse.lemminx.utils.ServerInfo; +import org.eclipse.lemminx.utils.platform.Platform; import org.eclipse.lsp4j.Command; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.InitializeResult; @@ -86,17 +88,18 @@ public class XMLLanguageServer private final ScheduledExecutorService delayer; private Integer parentProcessId; private XMLCapabilityManager capabilityManager; + private TelemetryManager telemetryManager; public XMLLanguageServer() { xmlTextDocumentService = new XMLTextDocumentService(this); xmlWorkspaceService = new XMLWorkspaceService(this); - + xmlLanguageService = new XMLLanguageService(); xmlLanguageService.setDocumentProvider(this); xmlLanguageService.setNotificationService(this); xmlLanguageService.setCommandService(xmlWorkspaceService); xmlLanguageService.setValidationService(this); - + delayer = Executors.newScheduledThreadPool(1); } @@ -108,7 +111,7 @@ public CompletableFuture initialize(InitializeParams params) { LogHelper.initializeRootLogger(languageClient, settings == null? null : settings.getLogs()); - LOGGER.info("Initializing XML Language server" + System.lineSeparator() + new ServerInfo().details()); + LOGGER.info("Initializing XML Language server" + System.lineSeparator() + Platform.details()); this.parentProcessId = params.getProcessId(); @@ -135,18 +138,19 @@ public CompletableFuture initialize(InitializeParams params) { * turn on/off * * (non-Javadoc) - * + * * @see org.eclipse.lsp4j.services.LanguageServer#initialized(org.eclipse.lsp4j. * InitializedParams) */ @Override public void initialized(InitializedParams params) { capabilityManager.initializeCapabilities(); + getTelemetryManager().onInitialized(params); } /** * Update XML settings configured from the client. - * + * * @param initOptions the XML settings */ public synchronized void updateSettings(Object initOptions) { @@ -155,7 +159,7 @@ public synchronized void updateSettings(Object initOptions) { /** * Update XML settings configured from the client. - * + * * @param initOptions Settings the XML settings * @param initLogs whether to initialize the log handlers */ @@ -168,10 +172,15 @@ private synchronized void updateSettings(Object initOptions, boolean initLogs) { XMLGeneralClientSettings xmlClientSettings = XMLGeneralClientSettings.getGeneralXMLSettings(initSettings); if (xmlClientSettings != null) { if (initLogs) { - // Update logs settings + // Update logs settings LogHelper.initializeRootLogger(languageClient, xmlClientSettings.getLogs()); } - + + XMLTelemetrySettings newTelemetry = xmlClientSettings.getTelemetry(); + if (newTelemetry != null) { + getTelemetryManager().setEnabled(newTelemetry.isEnabled()); + } + // Update format settings XMLFormattingOptions formatterSettings = xmlClientSettings.getFormat(); if (formatterSettings != null) { @@ -244,6 +253,7 @@ public WorkspaceService getWorkspaceService() { public void setClient(LanguageClient languageClient) { this.languageClient = (XMLLanguageClientAPI) languageClient; capabilityManager = new XMLCapabilityManager(this.languageClient, xmlTextDocumentService); + telemetryManager = new TelemetryManager(languageClient); } public XMLLanguageClientAPI getLanguageClient() { @@ -298,7 +308,7 @@ public void sendNotification(String message, MessageType messageType, Command... // the open settings command is not supported by the client, display a simple // message with LSP languageClient.showMessage(new MessageParams(messageType, message)); - } + } } @Override @@ -322,5 +332,14 @@ public void validate(DOMDocument document) { public XMLCapabilityManager getCapabilityManager() { return capabilityManager; } - + + /** + * Returns the telemetry manager. + * + * @return the telemetry manager. + */ + public TelemetryManager getTelemetryManager() { + return telemetryManager; + } + } diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/commons/ParentProcessWatcher.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/commons/ParentProcessWatcher.java index f58511ace..d19dc13f7 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/commons/ParentProcessWatcher.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/commons/ParentProcessWatcher.java @@ -12,7 +12,7 @@ *******************************************************************************/ package org.eclipse.lemminx.commons; -import static org.eclipse.lemminx.utils.OSUtils.isWindows; +import static org.eclipse.lemminx.utils.platform.Platform.isWindows; import java.io.IOException; import java.util.concurrent.Executors; @@ -113,9 +113,9 @@ private boolean parentProcessStillRunning() { if (!finished) { process.destroyForcibly(); } - // Terminating or destroying the Process doesn't close the process handle on Windows. + // Terminating or destroying the Process doesn't close the process handle on Windows. // It is only closed when the Process object is garbage collected (in its finalize() method). - // On Windows, when the Java LS is idle, we need to explicitly request a GC, + // On Windows, when the Java LS is idle, we need to explicitly request a GC, // to prevent an accumulation of zombie processes, as finalize() will be called. if (isWindows) { // Java >= 9 doesn't close the handle when the process is garbage collected diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/general/completion/FilePathCompletionParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/general/completion/FilePathCompletionParticipant.java index b5afb21ce..9bbb367d1 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/general/completion/FilePathCompletionParticipant.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/general/completion/FilePathCompletionParticipant.java @@ -13,8 +13,8 @@ package org.eclipse.lemminx.extensions.general.completion; import static org.eclipse.lemminx.utils.FilesUtils.getFilePathSlash; -import static org.eclipse.lemminx.utils.OSUtils.isWindows; import static org.eclipse.lemminx.utils.StringUtils.isEmpty; +import static org.eclipse.lemminx.utils.platform.Platform.isWindows; import java.io.File; import java.io.FilenameFilter; @@ -43,29 +43,29 @@ /** * Extension to support completion for file, folder path in: - * + * * - * + * *

- * + * *

*/ public class FilePathCompletionParticipant extends CompletionParticipantAdapter { @@ -152,7 +152,7 @@ private static void addCompletionItems(String value, ICompletionRequest request, /** * Returns the IO Path from the given value path. - * + * * @param valuePath the value path * @param xmlFileUri the XML file URI where completion has been triggered. * @return the IO Path from the given value path. @@ -179,7 +179,7 @@ private static Path getPath(String valuePath, String xmlFileUri) { /** * Returns a Range that covers trailing content after a slash, or if it already * ends with a slash then a Range right after it. - * + * * @param xmlDocument * @param fullRange * @param attributeValue @@ -218,7 +218,7 @@ private static Range adjustReplaceRange(DOMDocument xmlDocument, Range fullRange /** * Creates the completion items based off the given absolute path - * + * * @param pathToAttributeDirectory * @param attributePath * @param replaceRange diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLGeneralClientSettings.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLGeneralClientSettings.java index 2cbf6c57b..451cbe933 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLGeneralClientSettings.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLGeneralClientSettings.java @@ -16,19 +16,19 @@ /** * Class to hold all settings from the client side. - * + * * See https://github.com/eclipse/lemminx/blob/master/docs/Configuration.md for more * information. - * + * * This class is created through the deseralization of a JSON object. Each * internal setting must be represented by a class and have: - * + * * 1) A constructor with no parameters - * + * * 2) The JSON key/parent for the settings must have the same name as a varible. - * + * * eg: {"format" : {...}, "completion" : {...}} - * + * * In this class must exist both a "format" and "completion" variable with the * appropriate Class to represent the value of each key * @@ -49,6 +49,8 @@ public class XMLGeneralClientSettings { private XMLPreferences preferences; + private XMLTelemetrySettings telemetry; + public void setLogs(LogsSettings logs) { this.logs = logs; } @@ -67,7 +69,7 @@ public void setSymbols(XMLSymbolSettings symbols) { /** * Returns the code lens settings. - * + * * @return the code lens settings. */ public XMLCodeLensSettings getCodeLens() { @@ -76,7 +78,7 @@ public XMLCodeLensSettings getCodeLens() { /** * Sets the code lens settings. - * + * * @param codeLens */ public void setCodeLens(XMLCodeLensSettings codeLens) { @@ -85,7 +87,7 @@ public void setCodeLens(XMLCodeLensSettings codeLens) { /** * Sets the formatting options - * + * * @param format */ public void setFormat(XMLFormattingOptions format) { @@ -94,7 +96,7 @@ public void setFormat(XMLFormattingOptions format) { /** * Returns the formatting options - * + * * @return the formatting options */ public XMLFormattingOptions getFormat() { @@ -103,7 +105,7 @@ public XMLFormattingOptions getFormat() { /** * Sets the completion settings - * + * * @param completion */ public void setCompletion(XMLCompletionSettings completion) { @@ -112,7 +114,7 @@ public void setCompletion(XMLCompletionSettings completion) { /** * Returns the completion settings - * + * * @return the completion settings */ public XMLCompletionSettings getCompletion() { @@ -121,7 +123,7 @@ public XMLCompletionSettings getCompletion() { /** * Returns the XML preferences - * + * * @return the XML preferences */ public XMLPreferences getPreferences() { @@ -130,8 +132,8 @@ public XMLPreferences getPreferences() { /** * Sets the XML preferences - * - * @param preferences + * + * @param preferences the XML preferences */ public void setPreferences(XMLPreferences preferences) { this.preferences = preferences; @@ -139,7 +141,7 @@ public void setPreferences(XMLPreferences preferences) { /** * Returns the server - * + * * @return the server */ public ServerSettings getServer() { @@ -148,17 +150,35 @@ public ServerSettings getServer() { /** * Sets the server - * + * * @param server */ public void setServer(ServerSettings server) { this.server = server; } + /** + * Returns the telemetry settings + * + * @return the telemetry settings + */ + public XMLTelemetrySettings getTelemetry() { + return telemetry; + } + + /** + * Sets the telemetry settings + * + * @param telemetry the telemetry settings + */ + public void setTelemetry(XMLTelemetrySettings telemetry) { + this.telemetry = telemetry; + } + /** * Returns a new instance of XMLGeneralClientSettings * with contents from initializationOptionsSettings - * + * * @param initializationOptionsSettings * @return a new instance of XMLGeneralClientSettings * with contents from initializationOptionsSettings diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLTelemetrySettings.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLTelemetrySettings.java new file mode 100644 index 000000000..7c0ca17b5 --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/settings/XMLTelemetrySettings.java @@ -0,0 +1,42 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.settings; + +/** + * Settings for telemetry + * + * @author datho7561 + */ +public class XMLTelemetrySettings { + + private boolean enabled = false; + + public XMLTelemetrySettings() { + } + + /** + * Returns true if telemetry is enabled and false otherwise + * + * @return true if telemetry is enabled and false otherwise + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Set if telemetry should be enabled + * + * @param enabled true if telemetry should be enabled, and false if telemetry should be disabled + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + +} diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/InitializationTelemetryInfo.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/InitializationTelemetryInfo.java new file mode 100644 index 000000000..29fc26d7b --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/InitializationTelemetryInfo.java @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (c) 2019 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.telemetry; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.lemminx.utils.platform.JVM; +import org.eclipse.lemminx.utils.platform.Memory; +import org.eclipse.lemminx.utils.platform.Platform; + +/** + * Telemetry data to collect. + * + * + * + * @author Angelo ZERR + * + */ +public class InitializationTelemetryInfo { + + public static final String JVM_MEMORY_MAX = "jvm_memory_max"; + public static final String JVM_MEMORY_TOTAL = "jvm_memory_total"; + public static final String JVM_MEMORY_FREE = "jvm_memory_free"; + public static final String JVM_IS_NATIVE_IMAGE = "server_is_native"; + public static final String JVM_RUNTIME = "jvm_runtime"; + public static final String JVM_VERSION = "jvm_version"; + public static final String JVM_NAME = "jvm_name"; + public static final String SERVER_VERSION_NUMBER = "server_version"; + + /** + * Returns the init telemetry as a map + * + * @return the init telemetry as a map + */ + public static Map getInitializationTelemetryInfo() { + Map initTelemetry = new HashMap<>(); + + initTelemetry.put(SERVER_VERSION_NUMBER, Platform.getVersion().getVersionNumber()); + + JVM jvm = Platform.getJVM(); + + initTelemetry.put(JVM_NAME, jvm.getName()); + initTelemetry.put(JVM_VERSION, jvm.getVersion()); + initTelemetry.put(JVM_RUNTIME, jvm.getRuntime()); + initTelemetry.put(JVM_IS_NATIVE_IMAGE, jvm.isNativeImage()); + + Memory memory = jvm.getMemory(); + + initTelemetry.put(JVM_MEMORY_FREE, memory.getFree()); + initTelemetry.put(JVM_MEMORY_TOTAL, memory.getTotal()); + initTelemetry.put(JVM_MEMORY_MAX, memory.getMax()); + + return initTelemetry; + } + +} diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/OSUtils.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/TelemetryEvent.java similarity index 54% rename from org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/OSUtils.java rename to org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/TelemetryEvent.java index 745d06b69..9816b7e74 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/OSUtils.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/TelemetryEvent.java @@ -1,21 +1,29 @@ /******************************************************************************* -* Copyright (c) 2019 Red Hat Inc. and others. +* Copyright (c) 2021 Red Hat Inc. and others. * All rights reserved. This program and the accompanying materials * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v20.html * -* SPDX-License-Identifier: EPL-2.0 -* * Contributors: * Red Hat Inc. - initial API and implementation *******************************************************************************/ -package org.eclipse.lemminx.utils; +package org.eclipse.lemminx.telemetry; /** - * OSUtils + * Telemetry event + * */ -public class OSUtils { - - public static final boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("win") >= 0; - +public class TelemetryEvent { + + public final String name; + public final Object properties; + + TelemetryEvent() { + this("", null); + } + + TelemetryEvent(String name, Object properties) { + this.name = name; + this.properties = properties; + } } \ No newline at end of file diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/TelemetryManager.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/TelemetryManager.java new file mode 100644 index 000000000..e6d80151a --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/telemetry/TelemetryManager.java @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (c) 2019 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.telemetry; + +import org.eclipse.lsp4j.InitializedParams; +import org.eclipse.lsp4j.services.LanguageClient; + +/** + * Telemetry manager. + * + * @author Angelo ZERR + */ +public class TelemetryManager { + + /** + * "startup" telemetry event name + */ + private static final String STARTUP_EVENT_NAME = "server_initialized"; + + private final LanguageClient languageClient; + + private boolean enabled; + + public TelemetryManager(LanguageClient languageClient) { + this.languageClient = languageClient; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + /** + * Send a telemetry event on start of the XML server + * + * @param params + */ + public void onInitialized(InitializedParams params) { + if (isEnabled()) { + telemetryEvent(STARTUP_EVENT_NAME, InitializationTelemetryInfo.getInitializationTelemetryInfo()); + } + } + + /** + * The telemetry notification is sent from the server to the client to ask the + * client to log a telemetry event. + */ + private void telemetryEvent(String eventName, Object object) { + languageClient.telemetryEvent(new TelemetryEvent(eventName, object)); + } + +} diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/FilesUtils.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/FilesUtils.java index ec72484ef..d8c21f62e 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/FilesUtils.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/FilesUtils.java @@ -31,6 +31,8 @@ import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import org.eclipse.lemminx.utils.platform.Platform; + /** * Files utilities. * @@ -76,7 +78,7 @@ public static void resetDeployPath() { /** * Given a file path as a string, will normalize it and return the normalized * string if valid, or null if not. - * + * * The '~' home symbol will be converted into the actual home path. Slashes will * be corrected depending on the OS. */ @@ -114,7 +116,7 @@ private static Path getDeployedBasePath() { /** * Returns the deployed path from the given path. - * + * * @param path the path * @return the deployed path from the given path. * @throws IOException @@ -126,7 +128,7 @@ public static Path getDeployedPath(Path path) throws IOException { /** * Save the given input stream in in the give out file * outFile - * + * * @param in the input stream * @param outFile the output file * @throws IOException @@ -138,7 +140,7 @@ public static void saveToFile(InputStream in, Path outFile) throws IOException { /** * Save the given String content in the give out file * outFile - * + * * @param content the string content * @param outFile the output file * @throws IOException @@ -174,7 +176,7 @@ public static int getOffsetAfterScheme(String uri) { /** * Returns the slash ("/" or "\") that is used by the given string. If no slash * is given "/" is returned by default. - * + * * @param text * @return */ @@ -187,7 +189,7 @@ public static String getFilePathSlash(String text) { /** * Ensures there is no slash before a drive letter, and forces use of '\' - * + * * @param pathString * @return */ @@ -216,9 +218,9 @@ public static boolean isIncludedInDeployedPath(Path resourceCachePath) { /** * Remove the file:// scheme from the given file URI. - * + * * @param fileURI the file URI. - * + * * @return the file URI without file scheme. */ public static String removeFileScheme(String fileURI) { @@ -240,19 +242,19 @@ private static String removeFileScheme(String fileURI, boolean removeLastSlash) /** * Returns the IO Path from the given uri. This URI can use several syntaxes * like: - * + * *
    *
  • file:///C:/folder (Windows OS), file://home (Linux OS)
  • *
  • a%20b/folder (folder with spaces)
  • *
- * + * * @param uri the URI - * + * * @return the IO Path from the given uri. */ public static Path getPath(String uri) { // Remove file:// - uri = removeFileScheme(uri, OSUtils.isWindows); + uri = removeFileScheme(uri, Platform.isWindows); try { // replace "%20" with " ", "%3A" with ":", etc uri = URLDecoder.decode(uri, StandardCharsets.UTF_8.name()); @@ -264,9 +266,9 @@ public static Path getPath(String uri) { /** * Replace spaces with "%20". - * + * * @param path the path. - * + * * @return the path with replaced spaces. */ public static String encodePath(String path) { diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/ServerInfo.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/ServerInfo.java deleted file mode 100644 index 50f616cd0..000000000 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/ServerInfo.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2020 Red Hat Inc. and others. -* All rights reserved. This program and the accompanying materials -* which accompanies this distribution, and is available at -* http://www.eclipse.org/legal/epl-v20.html -* -* SPDX-License-Identifier: EPL-2.0 -* -* Contributors: -* Red Hat Inc. - initial API and implementation -*******************************************************************************/ -package org.eclipse.lemminx.utils; - -import static java.lang.System.lineSeparator; - -import java.util.Properties; -import java.util.ResourceBundle; - -public class ServerInfo { - private Properties sysProps; - - static final String MASTER = "master"; - - // https://github.com/oracle/graal/blob/master/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java#L97 - private static final boolean IS_NATIVE_IMAGE = "Substrate VM".equals(System.getProperty("java.vm.name")); - - private ResourceBundle rb = ResourceBundle.getBundle("git"); - - public ServerInfo() { - this(null); - } - - //For testing purposes - ServerInfo(Properties props) { - this.sysProps = new Properties(props == null?System.getProperties():props); - } - - /** - * @return the server version - */ - public String getVersion() { - return rb.getString("git.build.version"); - } - - /** - * @return the git commit id, used to build the server - */ - public String getShortCommitId() { - return rb.getString("git.commit.id.abbrev"); - } - - /** - * @return the git commit message, used to build the server - */ - public String getCommitMessage() { - return rb.getString("git.commit.message.short"); - } - - /** - * @return the Java Home used to launch the server - */ - public String getJava() { - return sysProps.getProperty("java.home", "unknown"); - } - - /** - * @return the git branch used to build the server - */ - public String getBranch() { - return rb.getString("git.branch"); - } - - @Override - public String toString() { - return getVersion(); - } - - /** - * Returns the server details, using the format:
- *
-   * LemMinX Server info:
-   *  - Version : (build version)
-   *  - Java : (path to java.home])
-   *  - Git : ([Branch] short commit id - commit message)
-   * 
- * - * @return the formatted server details - */ - public String details() { - StringBuilder details = new StringBuilder(); - details.append("LemMinX Server info:"); - append(details, "Version", getVersion()); - if (IS_NATIVE_IMAGE) { - append(details, "Native Image", null); - } else { - append(details, "Java", getJava()); - } - append(details, "VM Version", System.getProperty("java.vm.version")); - append(details, "Git", null); - String branch = getBranch(); - if (!MASTER.equals(branch)) { - details.append(" [Branch ") - .append(branch) - .append("]"); - } - details.append(" ") - .append(getShortCommitId()) - .append(" - ") - .append(getCommitMessage()); - return details.toString(); - } - - private void append(StringBuilder sb, String key, String value){ - sb.append(lineSeparator()) - .append(" - ") - .append(key); - if (value != null) { - sb.append(" : ") - .append(value); - } - } -} diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/JVM.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/JVM.java new file mode 100644 index 000000000..3e78705ea --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/JVM.java @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.utils.platform; + +/** + * JVM information + * + */ +public class JVM { + + private final String name; + + private final String runtime; + + private final String version; + + private final boolean isNativeImage; + + private final Memory memory; + + private final String javaHome; + + public JVM() { + this.name = Platform.getSystemProperty("java.vm.name"); // ex : OpenJDK 64-Bit Server VM + this.runtime = Platform.getSystemProperty("java.runtime.name"); // ex : OpenJDK Runtime Environment + this.version = Platform.getSystemProperty("java.version"); // ex : 11 + this.memory = new Memory(); + this.isNativeImage = "Substrate VM".equals(System.getProperty("java.vm.name")); + this.javaHome = Platform.getSystemProperty("java.home"); + } + + /** + * Returns the JVM name + * + * @return the JVM name + */ + public String getName() { + return name; + } + + /** + * Returns the JVM version + * + * @return the JVM version + */ + public String getVersion() { + return version; + } + + /** + * Returns the JVM runtime name. + * + * @return the JVM runtime name. + */ + public String getRuntime() { + return runtime; + } + + /** + * Returns the information on the memory + * + * @return the information on the memory + */ + public Memory getMemory() { + return memory; + } + + /** + * Returns the value of the JAVA_HOME environment variable + * + * Do not include this information in telemetry, as it likely includes the + * user's name + * + * @return the value of the JAVA_HOME environment variable + */ + public String getJavaHome() { + return javaHome; + } + + /** + * Returns true if the server is a native image and false otherwise + * + * @return true if the server is a native image and false otherwise + */ + public boolean isNativeImage() { + return isNativeImage; + } +} \ No newline at end of file diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Memory.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Memory.java new file mode 100644 index 000000000..cf6cfc2a3 --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Memory.java @@ -0,0 +1,43 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.utils.platform; + +/** + * JVM memory information + * + */ +public class Memory { + + private final long free; + + private final long total; + + private final long max; + + Memory() { + super(); + this.free = Runtime.getRuntime().freeMemory(); + this.total = Runtime.getRuntime().totalMemory(); + this.max = Runtime.getRuntime().maxMemory(); + } + + public long getFree() { + return free; + } + + public long getTotal() { + return total; + } + + public long getMax() { + return max; + } + +} \ No newline at end of file diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/OS.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/OS.java new file mode 100644 index 000000000..f8e47e27f --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/OS.java @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.utils.platform; + +/** + * OS information + */ +public class OS { + + private final String name; + + private final String version; + + private final String arch; + + private final transient boolean isWindows; + + public OS() { + this.name = Platform.getSystemProperty("os.name"); + this.version = Platform.getSystemProperty("os.version"); + this.arch = Platform.getSystemProperty("os.arch"); + isWindows = name != null && name.toLowerCase().indexOf("win") >= 0; + } + + /** + * Returns the OS name. + * + * @return the OS name. + */ + public String getName() { + return name; + } + + /** + * Returns the OS version. + * + * @return the OS version. + */ + public String getVersion() { + return version; + } + + /** + * Returns the OS arch. + * + * @return the OS arch. + */ + public String getArch() { + return arch; + } + + /** + * Returns true if the operating system is Windows and false otherwise + * + * @return true if the operating system is Windows and false otherwise + */ + public boolean isWindows() { + return isWindows; + } +} \ No newline at end of file diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Platform.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Platform.java new file mode 100644 index 000000000..3c59e4929 --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Platform.java @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.utils.platform; + +import org.eclipse.lemminx.utils.StringUtils; + +/** + * Platform information about OS and JVM. + */ +public class Platform { + + private static final String UNKNOWN_VALUE = "unknown"; + + private static final OS os = new OS(); + private static final JVM jvm = new JVM(); + private static final Version version = new Version(); + + public static final boolean isWindows = getOS().isWindows(); + public static String SLASH = isWindows ? "\\" : "/"; + + private Platform() { + } + + /** + * Returns the OS information + * + * @return the OS information + */ + public static OS getOS() { + return os; + } + + /** + * Returns the JVM information + * + * @return the JVM information + */ + public static JVM getJVM() { + return jvm; + } + + /** + * Returns the version information + * + * @return the version information + */ + public static Version getVersion() { + return version; + } + + /** + * Returns the system property from the given key and "unknown" otherwise. + * + * @param key the property system key + * @return the system property from the given key and "unknown" otherwise. + */ + static String getSystemProperty(String key) { + try { + String property = System.getProperty(key); + return StringUtils.isEmpty(property) ? UNKNOWN_VALUE : property; + } catch (SecurityException e) { + return UNKNOWN_VALUE; + } + } + + /** + * Returns the server details, using the format:
+ * + *
+	 * LemMinX Server info:
+	 *  - Version : (build version)
+	 *  - Java : (path to java.home])
+	 *  - Git : ([Branch] short commit id - commit message)
+	 * 
+ * + * @return the formatted server details + */ + public static String details() { + StringBuilder details = new StringBuilder(); + details.append("LemMinX Server info:"); + append(details, "Version", version.getVersionNumber()); + if (jvm.isNativeImage()) { + append(details, "Native Image", null); + } else { + append(details, "Java", jvm.getJavaHome()); + } + append(details, "VM Version", jvm.getVersion()); + append(details, "Git", null); + String branch = version.getBranch(); + if (!Version.MAIN_BRANCH.equals(branch)) { + details.append(" [Branch ").append(branch).append("]"); + } + details.append(" ").append(version.getShortCommitId()).append(" - ").append(version.getCommitMessage()); + return details.toString(); + } + + private static void append(StringBuilder sb, String key, String value) { + sb.append(System.lineSeparator()).append(" - ").append(key); + if (value != null) { + sb.append(" : ").append(value); + } + } +} \ No newline at end of file diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Version.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Version.java new file mode 100644 index 000000000..047daf860 --- /dev/null +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/utils/platform/Version.java @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.utils.platform; + +import java.util.ResourceBundle; + +/** + * LemMinX version information + * + * The information is read from git + */ +public class Version { + + private final String versionNumber; + + private final String shortCommitId; + + private final String commitMessage; + + private final String branch; + + public static final String MAIN_BRANCH = "master"; + + public Version() { + ResourceBundle rb = ResourceBundle.getBundle("git"); + versionNumber = rb.getString("git.build.version"); + shortCommitId = rb.getString("git.commit.id.abbrev"); + commitMessage = rb.getString("git.commit.message.short"); + branch = rb.getString("git.branch"); + } + + /** + * Returns the version number of LemMinX. + * + * @return the version number of LemMinX + */ + public String getVersionNumber() { + return versionNumber; + } + + /** + * Returns the git short commit id. + * + * eg. 4f2ed3d + * + * @return the git short commit id + */ + public String getShortCommitId() { + return shortCommitId; + } + + /** + * Returns the first line of the git commit message. + * + * @return the first line of the git commit message + */ + public String getCommitMessage() { + return commitMessage; + } + + /** + * Returns the git branch. + * + * @return the git branch + */ + public String getBranch() { + return branch; + } + +} \ No newline at end of file diff --git a/org.eclipse.lemminx/src/main/resources/META-INF/native-image/reflect-config.json b/org.eclipse.lemminx/src/main/resources/META-INF/native-image/reflect-config.json index 07752a01d..e021ad84f 100644 --- a/org.eclipse.lemminx/src/main/resources/META-INF/native-image/reflect-config.json +++ b/org.eclipse.lemminx/src/main/resources/META-INF/native-image/reflect-config.json @@ -206,6 +206,22 @@ "parameterTypes": [] }] }, + { + "name": "org.eclipse.lemminx.utils.platform.Memory", + "allDeclaredFields": true, + "methods": [{ + "name": "", + "parameterTypes": [] + }] + }, + { + "name": "org.eclipse.lemminx.utils.platform.Version", + "allDeclaredFields": true, + "methods": [{ + "name": "", + "parameterTypes": [] + }] + }, { "name": "org.eclipse.lemminx.services.CompletionResponse", "allDeclaredFields": true, @@ -285,6 +301,14 @@ "parameterTypes": [] }] }, + { + "name": "org.eclipse.lemminx.telemetry.TelemetryEvent", + "allDeclaredFields": true, + "methods": [{ + "name": "", + "parameterTypes": [] + }] + }, { "name": "org.eclipse.lemminx.extensions.contentmodel.settings.XMLNamespacesSettings", "allDeclaredFields": true, @@ -357,6 +381,14 @@ "parameterTypes": [] }] }, + { + "name": "org.eclipse.lemminx.settings.XMLTelemetrySettings", + "allDeclaredFields": true, + "methods": [{ + "name": "", + "parameterTypes": [] + }] + }, { "name": "org.eclipse.lsp4j.CallHierarchyCapabilities", "allDeclaredFields": true, diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/general/FilePathCompletionTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/general/FilePathCompletionTest.java index 9e1ac8d5e..39ef79e2c 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/general/FilePathCompletionTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/general/FilePathCompletionTest.java @@ -13,7 +13,7 @@ import static org.eclipse.lemminx.XMLAssert.c; import static org.eclipse.lemminx.XMLAssert.te; -import static org.eclipse.lemminx.utils.OSUtils.isWindows; +import static org.eclipse.lemminx.utils.platform.Platform.isWindows; import org.eclipse.lemminx.XMLAssert; import org.eclipse.lemminx.commons.BadLocationException; @@ -23,7 +23,7 @@ /** * FilePathCompletionTest - * + * * Test folders are in * org.eclipse.lemminx/src/test/resources/filePathCompletion/ */ diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/telemetry/TelemetryInitializationTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/telemetry/TelemetryInitializationTest.java new file mode 100644 index 000000000..b44127502 --- /dev/null +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/telemetry/TelemetryInitializationTest.java @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (c) 2021 Red Hat Inc. and others. +* All rights reserved. This program and the accompanying materials +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v20.html +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package org.eclipse.lemminx.telemetry; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lemminx.XMLLanguageServer; +import org.eclipse.lemminx.customservice.XMLLanguageClientAPI; +import org.eclipse.lemminx.utils.platform.Platform; +import org.eclipse.lsp4j.InitializeParams; +import org.eclipse.lsp4j.InitializedParams; +import org.eclipse.lsp4j.MessageActionItem; +import org.eclipse.lsp4j.MessageParams; +import org.eclipse.lsp4j.PublishDiagnosticsParams; +import org.eclipse.lsp4j.ShowMessageRequestParams; +import org.eclipse.lsp4j.services.LanguageServer; +import org.junit.jupiter.api.Test; + +/** + * Tests for telemetry + */ +public class TelemetryInitializationTest { + + @Test + public void telemetryEnabled() { + + List actualTelementryEvents = new ArrayList(); + XMLLanguageServer languageServer = createServer(actualTelementryEvents); + // By default telemetry is disabled, enable it + languageServer.getTelemetryManager().setEnabled(true); + initializeServer(languageServer); + + assertEquals(1, actualTelementryEvents.size()); + assertTrue(actualTelementryEvents.get(0).properties instanceof Map); + Map initTelemetry = (Map) actualTelementryEvents.get(0).properties; + assertEquals(Platform.getVersion().getVersionNumber(), initTelemetry.get(InitializationTelemetryInfo.SERVER_VERSION_NUMBER)); + assertNotNull(initTelemetry.get(InitializationTelemetryInfo.JVM_NAME), "Name of JVM is present"); + assertNotNull(initTelemetry.get(InitializationTelemetryInfo.JVM_MEMORY_MAX), "Memory information is present"); + assertFalse((Boolean)initTelemetry.get(InitializationTelemetryInfo.JVM_IS_NATIVE_IMAGE), "Not running under native-image (tests are set up to only run with the Java server)"); + + } + + @Test + public void telemetryDisabled() { + + List actualTelementryEvents = new ArrayList(); + XMLLanguageServer languageServer = createServer(actualTelementryEvents); + initializeServer(languageServer); + + assertEquals(0, actualTelementryEvents.size()); + + } + + private static void initializeServer(LanguageServer languageServer) { + // initialize -> no telemetry + InitializeParams params = new InitializeParams(); + languageServer.initialize(params); + + // initialized -> add telemetry + InitializedParams initialized = new InitializedParams(); + languageServer.initialized(initialized); + } + + private static XMLLanguageServer createServer(List actualTelementryEvents) { + // Create XML Language Server + XMLLanguageServer languageServer = new XMLLanguageServer(); + XMLLanguageClientAPI client = new XMLLanguageClientAPI() { + + @Override + public void telemetryEvent(Object object) { + actualTelementryEvents.add((TelemetryEvent) object); + } + + @Override + public CompletableFuture showMessageRequest(ShowMessageRequestParams requestParams) { + return null; + } + + @Override + public void showMessage(MessageParams messageParams) { + + } + + @Override + public void publishDiagnostics(PublishDiagnosticsParams diagnostics) { + + } + + @Override + public void logMessage(MessageParams message) { + + } + }; + languageServer.setClient(client); + return languageServer; + } + +} diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/utils/ServerInfoTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/utils/ServerInfoTest.java deleted file mode 100644 index 159ea5e5c..000000000 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/utils/ServerInfoTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2018-2020 Red Hat, Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v2.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v20.html - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Fred Bricon , Red Hat Inc. - initial API and implementation - */ -package org.eclipse.lemminx.utils; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class ServerInfoTest { - private static final String JAVA_HOME = "/foo/bar/java/"; - - private ServerInfo serverInfo; - - @BeforeEach - public void setup() { - Properties sysProps = new Properties(); - sysProps.setProperty("java.home", JAVA_HOME); - serverInfo = new ServerInfo(sysProps); - } - - @Test - public void testVersion() { - String version = serverInfo.getVersion(); - Pattern pattern = Pattern.compile("^(\\d+\\.\\d+\\.\\d+)(-.*)$"); - Matcher matcher = pattern.matcher(version); - assertTrue(matcher.matches(), "Unexpected format for :" + version); - } - - @Test - public void testJavaHome() { - assertEquals( JAVA_HOME, serverInfo.getJava(),"Unexpected Java home"); - } - - @Test - public void testGitInfos() { - assertNotNull(serverInfo.getBranch(), "Branch was not set"); - assertNotNull(serverInfo.getCommitMessage(), "Commit message was not set"); - assertNotNull(serverInfo.getShortCommitId(), "Commit id was not set"); - } - - @Test - public void testDetails() { - String details = serverInfo.details(); - //Check we didn't miss any info: - assertTrue(details.contains(serverInfo.getVersion()), "version is missing from the details"); - assertTrue(details.contains(serverInfo.getJava()), "Java is missing from the details"); - assertTrue(details.contains(serverInfo.getCommitMessage()), "commit message is missing from the details"); - assertTrue(details.contains(serverInfo.getShortCommitId()), "commit id is missing from the details"); - - String branch = serverInfo.getBranch(); - if (ServerInfo.MASTER.equals(branch)) { - assertFalse(details.contains(branch), "master branch should not be in the details"); - } else { - assertTrue(details.contains(branch), branch + " branch is missing from the details"); - } - } -} \ No newline at end of file diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/utils/platform/PlatformTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/utils/platform/PlatformTest.java new file mode 100644 index 000000000..214f3eab2 --- /dev/null +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/utils/platform/PlatformTest.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018-2021 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Fred Bricon , Red Hat Inc. - initial API and implementation + */ +package org.eclipse.lemminx.utils.platform; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +public class PlatformTest { + + @Test + public void testVersion() { + String version = Platform.getVersion().getVersionNumber(); + Pattern pattern = Pattern.compile("^(\\d+\\.\\d+\\.\\d+)(-.*)$"); + Matcher matcher = pattern.matcher(version); + assertTrue(matcher.matches(), "Unexpected format for :" + version); + } + + @Test + public void testGitInfos() { + assertNotNull(Platform.getVersion().getBranch(), "Branch was not set"); + assertNotNull(Platform.getVersion().getCommitMessage(), "Commit message was not set"); + assertNotNull(Platform.getVersion().getShortCommitId(), "Commit id was not set"); + } + + @Test + public void testDetails() { + String details = Platform.details(); + // Check we didn't miss any info: + assertTrue(details.contains(Platform.getVersion().getVersionNumber()), "version is missing from the details"); + assertTrue(details.contains(Platform.getJVM().getJavaHome()), "Java is missing from the details"); + assertTrue(details.contains(Platform.getVersion().getCommitMessage()), "commit message is missing from the details"); + assertTrue(details.contains(Platform.getVersion().getShortCommitId()), "commit id is missing from the details"); + + String branch = Platform.getVersion().getBranch(); + if (Version.MAIN_BRANCH.equals(branch)) { + assertFalse(details.contains(branch), "master branch should not be in the details"); + } else { + assertTrue(details.contains(branch), branch + " branch is missing from the details"); + } + } +} \ No newline at end of file