Fix for duplication and synchronization.
- Moved MusicFolderTestData from org.airsonic.player.service to org.airsonic.player.util
This commit is contained in:
+1
@@ -7,6 +7,7 @@ import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.PlayerService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.airsonic.player.util.MusicFolderTestData;
|
||||
import org.airsonic.player.util.StringUtil;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.domain.Album;
|
||||
import org.airsonic.player.domain.Artist;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.airsonic.player.util.MusicFolderTestData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.airsonic.player.util.MusicFolderTestData;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
|
||||
@ContextConfiguration(locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml"})
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
||||
@Component
|
||||
/**
|
||||
* Abstract class for scanning MusicFolder.
|
||||
*/
|
||||
public abstract class AbstractAirsonicHomeTest implements AirsonicHomeTest {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Currently, Maven is executing test classes in series,
|
||||
* so this class can hold the state.
|
||||
* When executing in parallel, subclasses should override this.
|
||||
*/
|
||||
private static AtomicBoolean dataBasePopulated = new AtomicBoolean();
|
||||
|
||||
// Above.
|
||||
private static AtomicBoolean dataBaseReady = new AtomicBoolean();
|
||||
|
||||
protected final static Function<String, String> resolveBaseMediaPath = (childPath) -> {
|
||||
return MusicFolderTestData.resolveBaseMediaPath().concat(childPath);
|
||||
};
|
||||
|
||||
@Autowired
|
||||
protected DaoHelper daoHelper;
|
||||
|
||||
@Autowired
|
||||
protected MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
protected MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
protected SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Override
|
||||
public AtomicBoolean dataBasePopulated() {
|
||||
return dataBasePopulated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtomicBoolean dataBaseReady() {
|
||||
return dataBaseReady;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void populateDatabaseOnlyOnce() {
|
||||
if (!dataBasePopulated().get()) {
|
||||
dataBasePopulated().set(true);
|
||||
getMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
try {
|
||||
// Await time to avoid scan failure.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s ->
|
||||
s.equals("MEDIA_FILE")
|
||||
| s.equals("ARTIST")
|
||||
| s.equals("MUSIC_FOLDER")
|
||||
| s.equals("ALBUM"))
|
||||
.forEach(tableName ->
|
||||
System.out.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
try {
|
||||
// Await for Lucene to finish writing(asynchronous).
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
dataBaseReady().set(true);
|
||||
} else {
|
||||
while (!dataBaseReady().get()) {
|
||||
try {
|
||||
// The subsequent test method waits while reading DB data.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.util.MusicFolderTestData;
|
||||
|
||||
/**
|
||||
* Test case interface for scanning MusicFolder.
|
||||
*/
|
||||
public interface AirsonicHomeTest {
|
||||
|
||||
/**
|
||||
* MusicFolder used by test class.
|
||||
*
|
||||
* @return MusicFolder used by test class
|
||||
*/
|
||||
default List<MusicFolder> getMusicFolders() {
|
||||
return MusicFolderTestData.getTestMusicFolders();
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the data input has been completed.
|
||||
*
|
||||
* @return Static AtomicBoolean indicating whether the data injection has been
|
||||
* completed
|
||||
*/
|
||||
abstract AtomicBoolean dataBasePopulated();
|
||||
|
||||
/**
|
||||
* Whether the data input has been completed.
|
||||
*
|
||||
* @return Static AtomicBoolean indicating whether the data injection has been
|
||||
* completed
|
||||
*/
|
||||
abstract AtomicBoolean dataBaseReady();
|
||||
|
||||
/**
|
||||
* Populate the database only once.
|
||||
* It is called in the @Before granted method.
|
||||
*/
|
||||
void populateDatabaseOnlyOnce();
|
||||
|
||||
}
|
||||
+15
-111
@@ -1,143 +1,47 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.MediaFile;
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.domain.RandomSearchCriteria;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/*
|
||||
* Tests to prove what kind of strings/chars can be used in the genre field.
|
||||
*/
|
||||
public class SearchServiceSpecialGenreTestCase {
|
||||
public class SearchServiceSpecialGenreTestCase extends AbstractAirsonicHomeTest {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private static Function<String, String> resolvePath = (childPath) ->{
|
||||
return MusicFolderTestData.resolveBaseMediaPath() + childPath;
|
||||
};
|
||||
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
private List<MusicFolder> getTestMusicFolders() {
|
||||
@Override
|
||||
public List<MusicFolder> getMusicFolders() {
|
||||
if (isEmpty(musicFolders)) {
|
||||
musicFolders = new ArrayList<>();
|
||||
|
||||
File musicDir = new File(resolvePath.apply("Search/SpecialGenre"));
|
||||
File musicDir = new File(resolveBaseMediaPath.apply("Search/SpecialGenre"));
|
||||
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
|
||||
|
||||
}
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
/*
|
||||
* A count to deliberately stagger the execution of populateDatabase.
|
||||
* If populate Database is called from multiple methods almost simultaneously,
|
||||
* it may not execute correctly.
|
||||
*/
|
||||
private int count = 1;
|
||||
|
||||
private synchronized void populateDatabase() {
|
||||
|
||||
try {
|
||||
Thread.sleep(300 * count++);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabaseOnlyOnce();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -152,7 +56,7 @@ public class SearchServiceSpecialGenreTestCase {
|
||||
@Test
|
||||
public void testQueryEscapeRequires() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
List<MusicFolder> folders = getMusicFolders();
|
||||
|
||||
Function<String, RandomSearchCriteria> simpleStringCriteria = s ->
|
||||
new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
@@ -222,7 +126,7 @@ public class SearchServiceSpecialGenreTestCase {
|
||||
@Test
|
||||
public void testBrackets() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
List<MusicFolder> folders = getMusicFolders();
|
||||
|
||||
RandomSearchCriteria criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"-(GENRE)-", // genre,
|
||||
@@ -254,7 +158,7 @@ public class SearchServiceSpecialGenreTestCase {
|
||||
@Test
|
||||
public void testNumericMapping() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
List<MusicFolder> folders = getMusicFolders();
|
||||
|
||||
RandomSearchCriteria criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"Rock", // genre,
|
||||
@@ -284,7 +188,7 @@ public class SearchServiceSpecialGenreTestCase {
|
||||
@Test
|
||||
public void testOthers() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
List<MusicFolder> folders = getMusicFolders();
|
||||
|
||||
RandomSearchCriteria criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"{'“『【【】】[︴○◎@ $〒→+]FULL-WIDTHCæsar's", // genre,
|
||||
|
||||
+11
-95
@@ -1,49 +1,21 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.MediaFile;
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
/*
|
||||
* Test cases related to #1139.
|
||||
* Confirming whether shuffle search can be performed correctly in MusicFolder containing special strings.
|
||||
@@ -54,95 +26,39 @@ import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
* This test case is a FalsePattern for search,
|
||||
* but there may be problems with the data flow prior to creating the search index.
|
||||
*/
|
||||
public class SearchServiceSpecialPathTestCase {
|
||||
public class SearchServiceSpecialPathTestCase extends AbstractAirsonicHomeTest {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private static Function<String, String> resolvePath = (childPath) ->{
|
||||
return MusicFolderTestData.resolveBaseMediaPath() + childPath;
|
||||
};
|
||||
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
private List<MusicFolder> getTestMusicFolders() {
|
||||
@Override
|
||||
public List<MusicFolder> getMusicFolders() {
|
||||
if (isEmpty(musicFolders)) {
|
||||
musicFolders = new ArrayList<>();
|
||||
|
||||
File musicDir = new File(resolvePath.apply("Search/SpecialPath/accessible"));
|
||||
File musicDir = new File(resolveBaseMediaPath.apply("Search/SpecialPath/accessible"));
|
||||
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
|
||||
|
||||
File music2Dir = new File(resolvePath.apply("Search/SpecialPath/accessible's"));
|
||||
File music2Dir = new File(resolveBaseMediaPath.apply("Search/SpecialPath/accessible's"));
|
||||
musicFolders.add(new MusicFolder(2, music2Dir, "accessible's", true, new Date()));
|
||||
|
||||
File music3Dir = new File(resolvePath.apply("Search/SpecialPath/accessible+s"));
|
||||
File music3Dir = new File(resolveBaseMediaPath.apply("Search/SpecialPath/accessible+s"));
|
||||
musicFolders.add(new MusicFolder(3, music3Dir, "accessible+s", true, new Date()));
|
||||
}
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
private synchronized void populateDatabase() {
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabaseOnlyOnce();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCharactersInDirName() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
List<MusicFolder> folders = getMusicFolders();
|
||||
|
||||
// ALL Songs
|
||||
List<MediaFile> randomAlbums = searchService.getRandomAlbums(Integer.MAX_VALUE, folders);
|
||||
|
||||
+9
-95
@@ -1,49 +1,21 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.domain.SearchCriteria;
|
||||
import org.airsonic.player.domain.SearchResult;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
/*
|
||||
* Test cases related to #1142.
|
||||
* The filter is not properly applied when analyzing the query,
|
||||
@@ -51,90 +23,32 @@ import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
* In the process of hardening the Analyzer implementation,
|
||||
* this problem is solved side by side.
|
||||
*/
|
||||
public class SearchServiceStartWithStopwardsTestCase {
|
||||
public class SearchServiceStartWithStopwardsTestCase extends AbstractAirsonicHomeTest {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private static Function<String, String> resolvePath = (childPath) ->{
|
||||
return MusicFolderTestData.resolveBaseMediaPath() + childPath;
|
||||
};
|
||||
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
private List<MusicFolder> getTestMusicFolders() {
|
||||
@Override
|
||||
public List<MusicFolder> getMusicFolders() {
|
||||
if (isEmpty(musicFolders)) {
|
||||
musicFolders = new ArrayList<>();
|
||||
|
||||
File musicDir = new File(resolvePath.apply("Search/StartWithStopwards"));
|
||||
File musicDir = new File(resolveBaseMediaPath.apply("Search/StartWithStopwards"));
|
||||
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
|
||||
|
||||
}
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
private synchronized void populateDatabase() {
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabaseOnlyOnce();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartWithStopwards() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
List<MusicFolder> folders = getMusicFolders();
|
||||
|
||||
final SearchCriteria criteria = new SearchCriteria();
|
||||
criteria.setCount(Integer.MAX_VALUE);
|
||||
|
||||
+17
-123
@@ -5,19 +5,13 @@ import com.codahale.metrics.ConsoleReporter;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.Timer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.AlbumDao;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MediaFileDao;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.Album;
|
||||
import org.airsonic.player.domain.Artist;
|
||||
import org.airsonic.player.domain.MediaFile;
|
||||
@@ -27,150 +21,50 @@ import org.airsonic.player.domain.ParamSearchResult;
|
||||
import org.airsonic.player.domain.RandomSearchCriteria;
|
||||
import org.airsonic.player.domain.SearchCriteria;
|
||||
import org.airsonic.player.domain.SearchResult;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.service.search.IndexType;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import org.subsonic.restapi.ArtistID3;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
public class SearchServiceTestCase {
|
||||
public class SearchServiceTestCase extends AbstractAirsonicHomeTest {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
@Autowired
|
||||
private AlbumDao albumDao;
|
||||
|
||||
private final MetricRegistry metrics = new MetricRegistry();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MediaFileDao mediaFileDao;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
|
||||
@Autowired
|
||||
private AlbumDao albumDao;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
populateDatabaseOnlyOnce();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private int count = 1;
|
||||
|
||||
/*
|
||||
* Cases susceptible to SerchService refactoring and version upgrades.
|
||||
* It is not exhaustive.
|
||||
*/
|
||||
private synchronized void populateDatabase() {
|
||||
@Test
|
||||
public void testSearchTypical() {
|
||||
|
||||
/*
|
||||
* It seems that there is a case that does not work well
|
||||
* if you test immediately after initialization in 1 method.
|
||||
* It may be improved later.
|
||||
* A simple test that is expected to easily detect API syntax differences when updating lucene.
|
||||
* Complete route coverage and data coverage in this case alone are not conscious.
|
||||
*/
|
||||
try {
|
||||
Thread.sleep(300 * count++);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
List<MusicFolder> allMusicFolders = musicFolderDao.getAllMusicFolders();
|
||||
Assert.assertEquals(3, allMusicFolders.size());
|
||||
|
||||
// *** testSearch() ***
|
||||
|
||||
MusicFolderTestData.getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
// Music Folder Music must have 3 children
|
||||
List<MediaFile> listeMusicChildren = mediaFileDao.getChildrenOf(
|
||||
new File(MusicFolderTestData.resolveMusicFolderPath()).getPath());
|
||||
Assert.assertEquals(3, listeMusicChildren.size());
|
||||
// Music Folder Music2 must have 1 children
|
||||
List<MediaFile> listeMusic2Children = mediaFileDao.getChildrenOf(
|
||||
new File(MusicFolderTestData.resolveMusic2FolderPath()).getPath());
|
||||
Assert.assertEquals(1, listeMusic2Children.size());
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchTypical() {
|
||||
|
||||
/*
|
||||
* A simple test that is expected to easily detect API syntax differences when updating lucene.
|
||||
* Complete route coverage and data coverage in this case alone are not conscious.
|
||||
*/
|
||||
|
||||
List<MusicFolder> allMusicFolders = musicFolderDao.getAllMusicFolders();
|
||||
Assert.assertEquals(3, allMusicFolders.size());
|
||||
|
||||
// *** testSearch() ***
|
||||
|
||||
String query = "Sarah Walker";
|
||||
final SearchCriteria searchCriteria = new SearchCriteria();
|
||||
searchCriteria.setQuery(query);
|
||||
searchCriteria.setCount(Integer.MAX_VALUE);
|
||||
searchCriteria.setOffset(0);
|
||||
String query = "Sarah Walker";
|
||||
final SearchCriteria searchCriteria = new SearchCriteria();
|
||||
searchCriteria.setQuery(query);
|
||||
searchCriteria.setCount(Integer.MAX_VALUE);
|
||||
searchCriteria.setOffset(0);
|
||||
|
||||
/*
|
||||
* _ID3_ALBUMARTIST_ Sarah Walker/Nash Ensemble
|
||||
|
||||
+2
-1
@@ -1,4 +1,4 @@
|
||||
package org.airsonic.player.dao;
|
||||
package org.airsonic.player.util;
|
||||
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
|
||||
@@ -38,4 +38,5 @@ public class MusicFolderTestData {
|
||||
liste.add(musicFolder2);
|
||||
return liste;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user