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

G2-1542 Enable matrix testing #386

Merged
merged 7 commits into from
Oct 22, 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
14 changes: 10 additions & 4 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,24 @@ on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 4
matrix:
os: [ubuntu-latest, windows-latest]
java_version: [17, 21]
runs-on: ${{ matrix.os }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.java_version }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: 17
java-version: ${{ matrix.java_version }}
cache: 'maven'
- name: Build with Maven
# Maven deploy on changes (or manual run) to master, otherwise just package it
run: mvn -s "${GITHUB_WORKSPACE}/.github/workflows/maven-settings.xml" -B ${{ (((github.event_name == 'push') || (github.event_name == 'workflow_dispatch')) && (github.ref == 'refs/heads/master')) && 'deploy' || 'package' }} --file pom.xml -Prelease,release-snapshot
run: mvn -s ".github/workflows/maven-settings.xml" -B ${{ (((github.event_name == 'push') || (github.event_name == 'workflow_dispatch')) && (github.ref == 'refs/heads/master') && (matrix.os == 'ubuntu-latest') && (matrix.java_version == '17')) && 'deploy' || 'package' }} --file pom.xml "-Prelease,release-snapshot"
env:
GITHUB_TOKEN: ${{ github.token }}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;

import com.g2forge.alexandria.compiler.diagnostic.DataDiagnostic;
import com.g2forge.alexandria.compiler.diagnostic.DiagnosticMatcher;
import com.g2forge.alexandria.java.core.helpers.HCollection;
import com.g2forge.alexandria.test.HAssert;

public class TestDynamicJavaCompiler {
Expand All @@ -34,7 +34,7 @@ public void error() throws ClassNotFoundException, URISyntaxException {
new DynamicJavaCompiler().compile("foo.bar.MyClass", text);
} catch (DynamicJavaCompilerException exception) {
final List<? extends Diagnostic<? extends JavaFileObject>> diagnostics = exception.getDiagnostics().stream().filter(d -> !d.getCode().startsWith("compiler.warn.proc.")).collect(Collectors.toList());
HAssert.assertThat(HCollection.getOne(diagnostics), new DiagnosticMatcher<>(new DataDiagnostic<>(Diagnostic.Kind.ERROR, null, 1l, text.indexOf("String"), "compiler.err.not.within.bounds", null)));
HAssert.assertThat(diagnostics, Matchers.hasItem(new DiagnosticMatcher<>(new DataDiagnostic<>(Diagnostic.Kind.ERROR, null, 1l, text.indexOf("String"), "compiler.err.not.within.bounds", null))));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.g2forge.alexandria.java.io.watch;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
Expand All @@ -10,6 +11,7 @@
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -44,12 +46,12 @@ public SimpleWatchEvent(WatchEvent<Path> watchEvent) {

@Test
public void create() throws IOException, InterruptedException {
test(null, (temp, file) -> writeFile(file, new byte[] { 0 }, StandardOpenOption.CREATE_NEW), StandardWatchEventKinds.ENTRY_CREATE);
test(null, (temp, file) -> writeFile(file, new byte[] { 0, 1, 2, 3 }, StandardOpenOption.CREATE_NEW), StandardWatchEventKinds.ENTRY_CREATE);
}

@Test
public void delete() throws IOException, InterruptedException {
test((temp, file) -> writeFile(file, new byte[] { 0 }, StandardOpenOption.CREATE_NEW), (temp, file) -> {
test((temp, file) -> writeFile(file, new byte[] { 0, 1, 2, 3 }, StandardOpenOption.CREATE_NEW), (temp, file) -> {
try {
Files.delete(file);
} catch (IOException exception) {
Expand All @@ -60,13 +62,15 @@ public void delete() throws IOException, InterruptedException {

@Test
public void modify() throws IOException, InterruptedException {
test((temp, file) -> writeFile(file, new byte[] { 0 }, StandardOpenOption.CREATE_NEW), (temp, file) -> writeFile(file, new byte[] { 1 }, StandardOpenOption.TRUNCATE_EXISTING), StandardWatchEventKinds.ENTRY_MODIFY);
test((temp, file) -> writeFile(file, new byte[] { 0, 1, 2, 3 }, StandardOpenOption.CREATE_NEW), (temp, file) -> writeFile(file, new byte[] { 1 }, StandardOpenOption.TRUNCATE_EXISTING), StandardWatchEventKinds.ENTRY_MODIFY);
}

@SafeVarargs
protected final void test(final IConsumer2<Path, Path> prep, final IConsumer2<Path, Path> modify, final Kind<Path>... kinds) throws InterruptedException {
try (final ICloseableSupplier<Path> temp = new TempDirectory(); final FileWatcher watcher = new FileWatcher()) {
try (final ICloseableSupplier<Path> temp = new TempDirectory();
final FileWatcher watcher = new FileWatcher()) {
final Path file = temp.get().resolve("file");
final Object delay = new Object();

// Prepare for testing
if (prep != null) prep.accept(temp.get(), file);
Expand All @@ -79,36 +83,51 @@ protected final void test(final IConsumer2<Path, Path> prep, final IConsumer2<Pa
events.add(event);
}
}, HCollection.asSet(kinds).toArray(new Kind[0]));
synchronized (events) {
events.wait(100);

// Delay to make sure we're watching when things happen
synchronized (delay) {
delay.wait(100);
}

// Perform the modification
if (modify != null) modify.accept(temp.get(), file);
synchronized (events) {
events.wait(100);
}

// Look for the expected events
final Set<SimpleWatchEvent> expected = Stream.of(kinds).map(k -> new SimpleWatchEvent(k, file.getFileName())).collect(Collectors.toSet());
synchronized (events) {
// Test for expected events
events.wait(1000);

final Set<SimpleWatchEvent> actual = events.stream().map(SimpleWatchEvent::new).collect(Collectors.toSet());
events.clear();
Assert.assertEquals(expected, actual);

// Make sure no more came in
events.wait(100);
Assert.assertEquals(HCollection.emptyList(), events.stream().map(SimpleWatchEvent::new).collect(Collectors.toList()));
final Set<SimpleWatchEvent> expected = Stream.of(kinds).map(k -> new SimpleWatchEvent(k, file.getFileName())).collect(Collectors.toCollection(LinkedHashSet::new));
int i = 0;
while (!expected.isEmpty() && (i < 20)) {
final Set<SimpleWatchEvent> actual;
synchronized (events) {
actual = events.stream().map(SimpleWatchEvent::new).collect(Collectors.toCollection(LinkedHashSet::new));
events.clear();
}
// Mark everything we found
expected.removeAll(actual);

// Wait a little while before we bother checking again
synchronized (delay) {
delay.wait(100);
}

i++;
}

// Make sure no more came in
Assert.assertEquals(new LinkedHashSet<>(), expected);
}
}

protected void writeFile(final Path file, byte[] bytes, OpenOption... options) {
try (final OutputStream output = Files.newOutputStream(file, options)) {
output.write(bytes);
output.flush();

if (output instanceof FileOutputStream) {
@SuppressWarnings("resource")
final FileOutputStream fileOutputStream = (FileOutputStream) output;
fileOutputStream.getChannel().force(true);
fileOutputStream.getFD().sync();
}
} catch (IOException exception) {
throw new RuntimeIOException(exception);
}
Expand Down
Loading