Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Dec 22, 2023
2 parents aaf5969 + 2970797 commit b44d01a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import org.eolang.maven.AssembleMojo;
import org.eolang.maven.Place;
import org.eolang.maven.footprint.FtDefault;
Expand Down Expand Up @@ -67,11 +71,9 @@ public OptCached(
@Override
public XML apply(final XML xml) {
try {
final Path path = new Place(xml.xpath("/program/@name").get(0))
.make(this.folder, AssembleMojo.IR_EXTENSION);
final XML optimized;
if (Files.exists(path)) {
optimized = new XMLDocument(path);
if (this.contains(xml)) {
optimized = new XMLDocument(this.cached(xml));
} else {
optimized = this.delegate.apply(xml);
new FtDefault(this.folder).save(
Expand All @@ -85,4 +87,39 @@ public XML apply(final XML xml) {
throw new IllegalStateException(String.format("Can't optimize '%s'", xml), ex);
}
}

/**
* Returns the path to the cached program.
* Pay attention that the path is not checked for existence.
* @param xml Eo program.
* @return Path to the cached program.
*/
private Path cached(final XML xml) {
return new Place(xml.xpath("/program/@name").get(0))
.make(this.folder, AssembleMojo.IR_EXTENSION);
}

/**
* Checks if the cache contains the program.
* @param xml Eo program.
* @return True if the cache contains the program.
* @throws IOException If fails.
*/
private boolean contains(final XML xml) throws IOException {
final Path path = this.cached(xml);
final Optional<String> time = xml.xpath("/program/@time").stream().findFirst();
final boolean res;
if (Files.exists(path) && time.isPresent()) {
res = Files.readAttributes(path, BasicFileAttributes.class)
.creationTime()
.toInstant()
.truncatedTo(ChronoUnit.SECONDS)
.equals(
ZonedDateTime.parse(time.get()).toInstant().truncatedTo(ChronoUnit.SECONDS)
);
} else {
res = false;
}
return res;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,47 +29,75 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.cactoos.bytes.BytesOf;
import org.cactoos.bytes.UncheckedBytes;
import org.cactoos.io.ResourceOf;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import org.eolang.maven.util.HmBase;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.hamcrest.io.FileMatchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.xembly.Directives;
import org.xembly.Xembler;

/**
* Test case for {@link org.eolang.maven.optimization.OptCached}.
* @since 0.28.12
*/
class OptCachedTest {
@Test
void optimizesIfXmlAlreadyInCache(final @TempDir Path tmp) throws IOException {
final XML program = OptCachedTest.program();
void returnsFromCacheIfXmlAlreadyInCache(@TempDir final Path tmp) throws IOException {
final XML program = OptCachedTest.program(ZonedDateTime.now());
OptCachedTest.save(tmp, program);
MatcherAssert.assertThat(
new OptCached(path -> program, tmp).apply(program),
"We expected that the program will be returned from the cache",
new OptCached(
path -> {
throw new IllegalStateException("This code shouldn't be executed");
},
tmp
).apply(program),
Matchers.equalTo(program)
);
}

@Test
void optimizesIfXmlIsAbsentInCache(final @TempDir Path tmp) {
void optimizesIfXmlIsAbsentInCache(@TempDir final Path tmp) {
final XML program = OptCachedTest.program();
final Path cache = tmp.resolve("cache");
final XML res = new OptCached(path -> program, cache)
.apply(program);
MatcherAssert.assertThat(
res,
Matchers.equalTo(program)
"We expect that the program will be created and returned as is (same instance)",
new OptCached(path -> program, cache).apply(program),
Matchers.sameInstance(program)
);
MatcherAssert.assertThat(
"We expect that the cache saved the program after the first run",
cache.resolve("main.xmir").toFile(),
FileMatchers.anExistingFile()
);
}

@Test
void optimizesBecauseChacheIsExpired(@TempDir final Path tmp) throws IOException {
final XML outdated = OptCachedTest.program(ZonedDateTime.now().minusMinutes(1));
final XML updated = OptCachedTest.program(ZonedDateTime.now());
OptCachedTest.save(tmp, outdated);
MatcherAssert.assertThat(
res, Matchers.equalTo(program)
"We expected that the program will be optimized because the cache is expired",
new OptCached(path -> updated, tmp).apply(outdated),
Matchers.equalTo(updated)
);
}

@Test
void optimizesIfTimeIsNotSet(@TempDir final Path tmp) throws IOException {
final XML without = OptCachedTest.program();
final XML with = OptCachedTest.program(ZonedDateTime.now());
OptCachedTest.save(tmp, without);
MatcherAssert.assertThat(
"We expected that the program will be optimized because the cache doesn't have time",
new OptCached(path -> with, tmp).apply(without),
Matchers.equalTo(with)
);
}

Expand All @@ -87,16 +115,34 @@ private static Path save(final Path tmp, final XML xml) throws IOException {
}

/**
* Get parsed program from resources.
* Generates EO program for tests.
* @return XML representation of program.
*/
private static XML program() {
return new XMLDocument(
new UncheckedBytes(
new BytesOf(
new ResourceOf("org/eolang/maven/optimize/main.xml")
)
).asBytes()
new Xembler(
new Directives()
.add("program")
.attr("name", "main")
.up()
).xmlQuietly()
);
}

/**
* Generates EO program for tests with specified time.
* @param time Time.
* @return XML representation of program.
*/
private static XML program(final ZonedDateTime time) {
return new XMLDocument(
new Xembler(
new Directives()
.add("program")
.attr("name", "main")
.attr("time", time.format(DateTimeFormatter.ISO_INSTANT))
.up()
).xmlQuietly()
);
}
}

0 comments on commit b44d01a

Please sign in to comment.