package tv.dyndns.kishibe.qmaclone.server; import static org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo; import static org.hamcrest.number.OrderingComparison.lessThanOrEqualTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import tv.dyndns.kishibe.qmaclone.client.constant.Constant; import tv.dyndns.kishibe.qmaclone.client.packet.PacketProblemMinimum; import tv.dyndns.kishibe.qmaclone.server.testing.QMACloneTestEnv; import tv.dyndns.kishibe.qmaclone.server.util.IntArray; import com.google.common.collect.HashMultiset; import com.google.common.collect.Lists; import com.google.common.collect.Multiset; import com.google.common.collect.Sets; import com.google.guiceberry.junit4.GuiceBerryRule; import com.google.inject.Inject; @RunWith(JUnit4.class) public class ThemeModeProblemManagerTest { private static final int LARGE_LOOP = 10000; @Rule public final GuiceBerryRule rule = new GuiceBerryRule(QMACloneTestEnv.class); @Inject private ThemeModeProblemManager manager; @Test public void testSelectProblemForThemeMode() throws InterruptedException { // 問題選択をLOOP回ランダムに行ってチェック final Random random = new Random(0); ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime() .availableProcessors() * 2); List<Callable<Void>> tasks = Lists.newArrayList(); for (int loop = 0; loop < LARGE_LOOP; ++loop) { tasks.add(new Callable<Void>() { @Override public Void call() throws Exception { assertSelectProblemShouldWork(random); return null; } }); } service.invokeAll(tasks); service.shutdown(); service.awaitTermination(1, TimeUnit.MINUTES); } private void assertSelectProblemShouldWork(final Random random) throws Exception { List<String> themes = Lists.newArrayList(manager.getThemesAndProblems().keySet()); String theme = themes.get(random.nextInt(themes.size())); Set<Integer> problemIds = Sets.newHashSet(); Set<Integer> selectedProblemIds = Sets.newHashSet(); for (int problemCount = 0; problemCount < Constant.MAX_PROBLEMS_PER_SESSION; ++problemCount) { int classLevel = random.nextInt(Constant.NUMBER_OF_CLASSES + 5); int difficultSelect = random.nextInt(5); PacketProblemMinimum problem = manager.selectProblem(theme, difficultSelect, classLevel, selectedProblemIds); assertNotNull(problem); selectedProblemIds.add(problem.id); } int numberOfProblems = problemIds.size(); assertEquals(Constant.MAX_PROBLEMS_PER_SESSION, numberOfProblems); assertEquals(problemIds, selectedProblemIds); } @Test public void testGetThemes() { Map<String, IntArray> themesAndProblems = manager.getThemesAndProblems(); List<List<String>> themes = manager.getThemes(); assertNotNull(themes); assertEquals(6, themes.size()); assertFalse(themes.get(0).isEmpty()); assertFalse(themes.get(1).isEmpty()); assertFalse(themes.get(2).isEmpty()); assertFalse(themes.get(3).isEmpty()); assertFalse(themes.get(4).isEmpty()); assertFalse(themes.get(5).isEmpty()); for (List<String> themesForEachGenre : themes) { for (String theme : themesForEachGenre) { assertThat(themesAndProblems.get(theme).size(), greaterThanOrEqualTo(Constant.MIN_NUMBER_OF_THEME_MODE_PROBLEMS)); } } } @Test public void testGetProblemTablesForThemeMode() { Map<String, IntArray> themesAndProblems = manager.getThemesAndProblems(); assertNotNull(themesAndProblems); assertFalse(themesAndProblems.isEmpty()); // for (Entry<String, IntArray> entry : themesAndProblems.entrySet()) { // IntArray problemIds = entry.getValue(); // assertFalse(entry.getKey(), problemIds.isEmpty()); // } } @Test public void selectProblemShouldNotSelectSameProblemSoMuch() throws Exception { Multiset<Integer> problemIds = HashMultiset.create(); for (int loop = 0; loop < 10; ++loop) { Set<Integer> selectedProblemIds = new HashSet<Integer>(); for (int problemCount = 0; problemCount < Constant.MAX_PROBLEMS_PER_SESSION; ++problemCount) { PacketProblemMinimum problem = manager.selectProblem("とある魔術の禁書", Constant.DIFFICULT_SELECT_NORMAL, Constant.CLASS_LEVEL_NORMAL, selectedProblemIds); problemIds.add(problem.id); } } for (int problemId : problemIds) { assertThat(problemIds.count(problemId), lessThanOrEqualTo(5)); } } }