Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: run tests also on MacOS and Windows #674

Merged
merged 1 commit into from
Jan 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 36 additions & 22 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
name: Build

on:
Expand Down Expand Up @@ -47,7 +47,15 @@ jobs:

build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
runs-on: ${{ matrix.os }}
timeout-minutes: 15

steps:
- name: Show environment variables
Expand All @@ -59,27 +67,28 @@ jobs:
fetch-depth: 0 # required to prevent tycho-p2-extras-plugin:compare-version-with-baseline potentially failing the build

- name: Configure Fast APT Mirror
if: runner.os == 'Linux'
uses: vegardit/fast-apt-mirror.sh@v1

- name: "Install: xvfb"
run: sudo apt-get install --no-install-recommends -y xvfb
- name: "Install: Linux packages"
if: runner.os == 'Linux'
run: |
set -eux
sudo apt-get install --no-install-recommends -y xvfb

- name: "Install: dbus-x11"
# prevents: "Failed to execute child process “dbus-launch” (No such file or directory)"
run: sudo apt-get install --no-install-recommends -y dbus-x11
# prevents: "Failed to execute child process “dbus-launch” (No such file or directory)"
sudo apt-get install --no-install-recommends -y dbus-x11

- name: "Install: at-spi2-core"
# prevents: "dbind-WARNING **: 20:17:55.046: AT-SPI: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files"
# see https://gist.github.com/jeffcogswell/62395900725acef1c0a5a608f7eb7a05
run: sudo apt-get install --no-install-recommends -y at-spi2-core
# prevents: "dbind-WARNING **: 20:17:55.046: AT-SPI: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files"
# see https://gist.github.com/jeffcogswell/62395900725acef1c0a5a608f7eb7a05
sudo apt-get install --no-install-recommends -y at-spi2-core

- name: "Install: lib-swt-gtk-*-java"
# prevents:
# java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
# no swt-pi4-gtk-4956r13 in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
# no swt-pi4-gtk in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
# no swt-pi4 in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
run: sudo apt-get install --no-install-recommends -y libswt-gtk-*-java
# prevents:
# java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
# no swt-pi4-gtk-4956r13 in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
# no swt-pi4-gtk in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
# no swt-pi4 in java.library.path: /usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib
sudo apt-get install --no-install-recommends -y libswt-gtk-*-java

- name: "Install: JDK ${{ env.JAVA_VERSION }}"
uses: actions/setup-java@v4 # https://github.com/actions/setup-java
Expand All @@ -105,20 +114,25 @@ jobs:
run: |
set -eu

MAVEN_OPTS+=" -Djava.security.egd=file:/dev/./urandom" # https://stackoverflow.com/questions/58991966/what-java-security-egd-option-is-for/59097932#59097932
if [[ "${{ runner.os }}" == "Windows" ]]; then
MAVEN_OPTS+=" -Djava.security.egd=file:/dev/urandom" # https://www.baeldung.com/java-security-egd#bd-testing-the-effect-of-javasecurityegd
else
MAVEN_OPTS+=" -Djava.security.egd=file:/dev/./urandom" # https://stackoverflow.com/questions/58991966/what-java-security-egd-option-is-for/59097932#59097932
fi
MAVEN_OPTS+=" -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS" # https://stackoverflow.com/questions/5120470/how-to-time-the-different-stages-of-maven-execution/49494561#49494561
MAVEN_OPTS+=" -Xmx1024m -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dhttps.protocols=TLSv1.2"
echo " -> MAVEN_OPTS: $MAVEN_OPTS"
export MAVEN_OPTS
echo "MAVEN_OPTS: $MAVEN_OPTS"

if [[ ${ACT:-} == "true" ]]; then # when running locally using nektos/act
maven_args="-Djgit.dirtyWorkingTree=warning"
else
maven_args="--no-transfer-progress"
fi

# prevent "org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]"
xvfb-run --server-args="-screen 0 1600x900x24" mvn \
# prevent "org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]" on Linux
${{ runner.os == 'Linux' && 'xvfb-run --server-args="-screen 0 1600x900x24" \' || '' }}
mvn \
--errors \
--update-snapshots \
--batch-mode \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/licensecheck.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
name: License check

on:
Expand Down
5 changes: 0 additions & 5 deletions org.eclipse.tm4e.languageconfiguration.tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<useUIHarness>true</useUIHarness>
<useUIThread>true</useUIThread>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
7 changes: 1 addition & 6 deletions org.eclipse.tm4e.ui.tests/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse</groupId>
Expand All @@ -16,11 +16,6 @@
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<useUIHarness>true</useUIHarness>
<useUIThread>true</useUIThread>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

public class TMPresentationReconcilerTypeScriptTest {
@Disabled
class TMPresentationReconcilerTypeScriptTest {

private IGrammar grammar;
private ITokenProvider theme;
private TMEditor editor;

@BeforeEach
void setup() throws Exception {
// TODO ignore these tests on GitHub Actions Windows runner because they are extremely slow (4-5min) for an unknown reason
org.junit.Assume.assumeFalse(TestUtils.isGitHubActions() && System.getProperty("os.name").toLowerCase().contains("windows"));

TestUtils.assertNoTM4EThreadsRunning();

grammar = new Registry().addGrammar(IGrammarSource.fromResource(getClass(), "/grammars/TypeScript.tmLanguage.json"));
Expand All @@ -46,7 +50,8 @@ void setup() throws Exception {

@AfterEach
void tearDown() throws InterruptedException {
editor.dispose();
if(editor != null)
editor.dispose();

TestUtils.assertNoTM4EThreadsRunning();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@

import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Control;
import org.eclipse.tm4e.ui.internal.utils.UI;
import org.eclipse.tm4e.ui.tests.support.TestUtils;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -53,15 +53,10 @@ void testTMHighlightInGenericEditor() throws IOException, PartInitException {
try (var fileOutputStream = new FileOutputStream(f)) {
fileOutputStream.write("let a = '';\nlet b = 10;\nlet c = true;".getBytes());
}
editor = IDE.openEditor(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(),
f.toURI(),
genericEditorDescr.getId(),
true);
editor = IDE.openEditor(UI.getActivePage(), f.toURI(), genericEditorDescr.getId(), true);

final StyledText text = (StyledText) editor.getAdapter(Control.class);
assertTrue(TestUtils.waitForCondition(3_000, text.getDisplay(),
() -> text.getStyleRanges().length > 1));
final var text = (StyledText) editor.getAdapter(Control.class);
assertTrue(TestUtils.waitForCondition(3_000, () -> text.getStyleRanges().length > 1));
}

@Test
Expand All @@ -70,20 +65,15 @@ void testTMHighlightInGenericEditorEdit() throws IOException, PartInitException
try (var fileOutputStream = new FileOutputStream(f)) {
fileOutputStream.write("let a = '';".getBytes());
}
editor = IDE.openEditor(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), f.toURI(),
genericEditorDescr.getId(),
true);
editor = IDE.openEditor(UI.getActivePage(), f.toURI(), genericEditorDescr.getId(), true);

final StyledText text = (StyledText) editor.getAdapter(Control.class);
assertTrue(TestUtils.waitForCondition(3_000, text.getDisplay(),
() -> text.getStyleRanges().length > 1));
final var text = (StyledText) editor.getAdapter(Control.class);
TestUtils.waitForAndAssertCondition(3_000, () -> text.getStyleRanges().length > 1);

final int initialNumberOfRanges = text.getStyleRanges().length;
text.setText("let a = '';\nlet b = 10;\nlet c = true;");
assertTrue(TestUtils.waitForCondition(3_000, text.getDisplay(),
() -> text.getStyleRanges().length > initialNumberOfRanges + 3),
"More styles should have been added");
TestUtils.waitForAndAssertCondition("More styles should have been added", 3_000,
() -> text.getStyleRanges().length > initialNumberOfRanges + 3);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
*/
package org.eclipse.tm4e.ui.tests.support;

import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.*;

import java.io.File;
import java.io.IOException;
import java.util.function.BooleanSupplier;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import org.eclipse.swt.widgets.Display;
import org.eclipse.tm4e.ui.internal.utils.UI;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
Expand All @@ -30,6 +32,11 @@

public final class TestUtils {

@FunctionalInterface
public interface Condition {
boolean isMet() throws Exception;
}

public static IEditorDescriptor assertHasGenericEditor() {
final var genericEditorDescr = PlatformUI.getWorkbench().getEditorRegistry()
.findEditor("org.eclipse.ui.genericeditor.GenericEditor");
Expand Down Expand Up @@ -60,7 +67,7 @@ public static void assertNoTM4EThreadsRunning() throws InterruptedException {
}
}

public static void closeEditor(IEditorPart editor) {
public static void closeEditor(final IEditorPart editor) {
if (editor == null)
return;
final IWorkbenchPartSite currentSite = editor.getSite();
Expand All @@ -72,27 +79,85 @@ public static void closeEditor(IEditorPart editor) {
}
}

public static File createTempFile(String fileNameSuffix) throws IOException {
public static File createTempFile(final String fileNameSuffix) throws IOException {
final var file = File.createTempFile("tm4e_testfile", fileNameSuffix);
file.deleteOnExit();
return file;
}

public static boolean isCI() {
return "true".equals(System.getenv("CI"));
return Boolean.getBoolean("CI");
}

public static boolean isGitHubActions() {
return Boolean.getBoolean("GITHUB_ACTIONS");
}

public static void waitForAndAssertCondition(int timeout_ms, Condition condition) {
waitForAndAssertCondition("Condition not met within expected time.", timeout_ms, condition);
}

public static void waitForAndAssertCondition(int timeout_ms, Display display, Condition condition) {
waitForAndAssertCondition("Condition not met within expected time.", timeout_ms, display, condition);
}

public static boolean waitForCondition(int timeout_ms, BooleanSupplier condition) {
return waitForCondition(timeout_ms, PlatformUI.getWorkbench().getDisplay(), condition);
public static void waitForAndAssertCondition(String errorMessage, int timeout_ms, Condition condition) {
waitForAndAssertCondition(errorMessage, timeout_ms, UI.getDisplay(), condition);
}

public static boolean waitForCondition(int timeout_ms, Display display, BooleanSupplier condition) {
return new DisplayHelper() {
public static void waitForAndAssertCondition(String errorMessage, int timeout_ms, Display display,
Condition condition) {
final var ex = new AtomicReference<Throwable>();
final var isConditionMet = new DisplayHelper() {
@Override
protected boolean condition() {
return condition.getAsBoolean();
try {
final var isMet = condition.isMet();
ex.set(null);
return isMet;
} catch (final AssertionError | Exception e) {
ex.set(e);
return false;
}
}
}.waitForCondition(display, timeout_ms, 50);
if (ex.get() != null) {
// if the condition was not met because of an exception throw it
if (ex.get() instanceof AssertionError ae) {
throw ae;
}
if (ex.get() instanceof RuntimeException re) {
throw re;
}
}.waitForCondition(display, timeout_ms);
throw new AssertionError(errorMessage, ex.get());
}
assertTrue(errorMessage, isConditionMet);
}

public static boolean waitForCondition(final int timeout_ms, final Condition condition) {
return waitForCondition(timeout_ms, UI.getDisplay(), condition);
}

public static boolean waitForCondition(final int timeout_ms, final Display display, final Condition condition) {
final var ex = new AtomicReference<Throwable>();
final var isConditionMet = new DisplayHelper() {
@Override
protected boolean condition() {
try {
final var isMet = condition.isMet();
ex.set(null);
return isMet;
} catch (final AssertionError | Exception e) {
ex.set(e);
return false;
}
}
}.waitForCondition(display, timeout_ms, 50);
if (ex.get() != null) {
// if the condition was not met because of an exception log it
ex.get().printStackTrace();
}
return isConditionMet;
}

private TestUtils() {
Expand Down
Loading
Loading