Skip to content

Commit

Permalink
#39 infinity loop
Browse files Browse the repository at this point in the history
  • Loading branch information
l3r8yJ committed Dec 1, 2022
1 parent b9636e5 commit 8054d05
Showing 1 changed file with 31 additions and 100 deletions.
131 changes: 31 additions & 100 deletions src/test/java/com/yegor256/tojos/MnSynchronizedTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,16 @@
*/
package com.yegor256.tojos;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Logger;

import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

/**
* Test case for {@link MnSynchronized}.
Expand All @@ -46,14 +42,15 @@
class MnSynchronizedTest {

/**
* Number of threads.
* The logger.
*/
static final int THREADS = 5;
private static final Logger LOGGER =
Logger.getLogger(MnSynchronizedTest.class.getName());

/**
* The number of changes in under-test mono.
* Number of threads.
*/
private final AtomicInteger counter = new AtomicInteger(0);
static final int THREADS = 5;

/**
* The mono under test.
Expand All @@ -65,10 +62,13 @@ class MnSynchronizedTest {
*/
private ExecutorService executor;

private CountDownLatch latch;

@BeforeEach
final void setUp() {
this.shared = new MnSynchronized(new MnMemory());
final void setUp(@TempDir final Path temp) {
this.shared = new MnSynchronized(new MnJson(temp.resolve("/bar/baz/a.json")));
this.executor = Executors.newFixedThreadPool(MnSynchronizedTest.THREADS);
this.latch = new CountDownLatch(1);
}

/**
Expand All @@ -80,107 +80,38 @@ final void setUp() {
*/
@Test
final void concurrentScenario() throws InterruptedException {
final Collection<Map<String, String>> addition = rowsByThreads();
for (int trds = 1; trds <= MnSynchronizedTest.THREADS; ++trds) {
this.executor.submit(
new MnSynchronizedTest.TestTask(
MnSynchronizedTest.rowsBySize(trds),
this.shared,
this.counter
)
() -> {
this.latch.await();
final Collection<Map<String, String>> increased = this.shared.read();
increased.addAll(addition);
this.shared.write(increased);
return this.shared.read().size();
}
);
}
this.executor.shutdown();
assert this.executor.awaitTermination(5L, TimeUnit.SECONDS);
this.latch.countDown();
assert this.executor.awaitTermination(30, TimeUnit.SECONDS);
MatcherAssert.assertThat(
this.counter.get(),
Matchers.equalTo(MnSynchronizedTest.expectedSize())
this.shared.read().size(),
Matchers.equalTo(25)
);
}

/**
* The expected.
*
* @return Sum of arithmetic progression from 1 to number of threads
*/
private static Integer expectedSize() {
final int len = MnSynchronizedTest.THREADS;
return len + (len - 1) * len / 2;
}

/**
* The rows to write.
*
* @param size The size of rows
* @return Collection of rows
*/
private static Collection<Map<String, String>> rowsBySize(final int size) {
private static Collection<Map<String, String>> rowsByThreads() {
final Map<String, String> row = new HashMap<>(0);
row.put(Tojos.KEY, String.valueOf(size));
final Collection<Map<String, String>> res = new ArrayList<>(size);
for (int idx = 0; idx < size; ++idx) {
row.put(Tojos.KEY, String.valueOf(MnSynchronizedTest.THREADS));
final Collection<Map<String, String>> res = new ArrayList<>(MnSynchronizedTest.THREADS);
for (int idx = 0; idx < MnSynchronizedTest.THREADS; ++idx) {
res.add(row);
}
return res;
}

/**
* The test task to concurrent read and write operations.
*
* @since 0.3.0
*/
private static final class TestTask implements Runnable {

/**
* The logger.
*/
private static final Logger LOGGER =
Logger.getLogger(MnSynchronizedTest.class.getName());

/**
* Local mono.
*/
private final Mono mono;

/**
* Rows to write.
*/
private final Collection<Map<String, String>> rows;

/**
* The counter.
*/
private final AtomicInteger counter;

/**
* Ctor.
*
* @param rws The rows to write
* @param mno The mono
* @param cntr The counter
*/
TestTask(
final Collection<Map<String, String>> rws,
final Mono mno,
final AtomicInteger cntr
) {
this.rows = rws;
this.mono = mno;
this.counter = cntr;
}

@Override
public void run() {
this.mono.write(this.rows);
this.counter.addAndGet(this.rows.size());
MnSynchronizedTest.TestTask.LOGGER.log(
Level.INFO,
String.format(
"Thread %s, written %d rows.\nReading:\n%s",
this,
this.rows.size(),
this.mono.read()
)
);
}
}
}

0 comments on commit 8054d05

Please sign in to comment.