package de.is24.infrastructure.gridfs.http.metadata; import de.is24.infrastructure.gridfs.http.category.LocalExecutionOnly; import de.is24.infrastructure.gridfs.http.domain.RepoEntry; import de.is24.infrastructure.gridfs.http.mongo.IntegrationTestContext; import de.is24.infrastructure.gridfs.http.storage.FileDescriptor; import de.is24.infrastructure.gridfs.http.storage.FileStorageItem; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.IOException; import java.util.Date; import java.util.List; import static de.is24.infrastructure.gridfs.http.utils.RepositoryUtils.uniqueRepoName; import static de.is24.infrastructure.gridfs.http.utils.RpmUtils.COMPLEX_RPM_FILE_NAME; import static de.is24.infrastructure.gridfs.http.utils.RpmUtils.streamOf; import static java.io.File.createTempFile; import static java.lang.System.currentTimeMillis; import static org.apache.commons.lang.time.DateUtils.addHours; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @Category(LocalExecutionOnly.class) public class MetadataServiceIT { @ClassRule public static IntegrationTestContext context = new IntegrationTestContext(); private MetadataService service; private String reponame; @Before public void setUp() throws Exception { service = context.metadataService(); reponame = uniqueRepoName(); } @Test public void generateYumRepoMetadata() throws Exception { long startTime = currentTimeMillis(); context.gridFsService().storeRpm(reponame, streamOf(COMPLEX_RPM_FILE_NAME)); service.generateYumMetadataIfNecessary(reponame); assertDbFile("primary"); assertDbFile("other"); assertDbFile("filelists"); assertRepoMdXml(); assertRepoMdXmlSignature(); final RepoEntry repoEntry = context.repoEntriesRepository().findFirstByName(reponame); assertThat(repoEntry.getLastMetadataGeneration().getTime(), greaterThan(startTime)); assertThat(repoEntry.getHashOfEntries(), is(notNullValue())); } @Test public void doNotGenerateMetadataIfNoRepoModificationWasMade() throws Exception { String reponame = uniqueRepoName(); context.repoService().createOrUpdate(reponame); RepoEntry repoEntryBefore = context.repoEntriesRepository().findFirstByName(reponame); repoEntryBefore.setHashOfEntries(context.entriesHashCalculator().hashForRepo(reponame)); repoEntryBefore.setLastMetadataGeneration(new Date()); context.repoEntriesRepository().save(repoEntryBefore); service.generateYumMetadataIfNecessary(reponame); RepoEntry repoEntryAfter = context.repoEntriesRepository().findFirstByName(reponame); assertThat(repoEntryAfter, is(repoEntryBefore)); } @Test public void cleanupOldMetadata() throws Exception { String reponame = uniqueRepoName(); Object sqliteFileId = givenSomeSqliteFileFromOneHourAgo(reponame); context.gridFsService().storeRpm(reponame, streamOf(COMPLEX_RPM_FILE_NAME)); service.generateYumMetadataIfNecessary(reponame); assertTrue(context.fileStorageService().findById(sqliteFileId).isMarkedAsDeleted()); } private Object givenSomeSqliteFileFromOneHourAgo(String reponame) throws IOException { String givenSqliteFilenameInfix = "other-123"; context.gridFsService() .storeRepodataDbBz2(reponame, createTempFile(reponame, "dummyfile"), givenSqliteFilenameInfix); FileStorageItem file = findSqLiteFile(reponame, givenSqliteFilenameInfix); assertThat(file, notNullValue()); context.fileStorageService().setUploadDate(file, addHours(new Date(), -1)); return file.getId(); } private FileStorageItem findSqLiteFile(String reponame, String givenSqliteFilenameInfix) { List<FileStorageItem> storageItems = context.fileStorageService() .findByPrefix(reponame + "/repodata/" + givenSqliteFilenameInfix); return (!storageItems.isEmpty()) ? storageItems.get(0) : null; } private void assertRepoMdXml() { FileDescriptor descriptor = new FileDescriptor(reponame, "repodata", "repomd.xml"); FileStorageItem storageItem = context.fileStorageService().findBy(descriptor); assertThat(storageItem, notNullValue()); } private void assertRepoMdXmlSignature() { FileDescriptor descriptor = new FileDescriptor(reponame, "repodata", "repomd.xml.asc"); FileStorageItem storageItem = context.fileStorageService().findBy(descriptor); assertThat(storageItem, notNullValue()); } private void assertDbFile(String type) { FileStorageItem dbFile = context.fileStorageService().findByPrefix(reponame + "/repodata/" + type).get(0); String sha256 = dbFile.getChecksumSha256(); assertThat(dbFile.getFilename(), endsWith(type + "-" + sha256 + ".sqlite.bz2")); assertFalse(dbFile.isMarkedAsDeleted()); } }