/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.cyclop.service.common; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; import java.util.UUID; import javax.inject.Inject; import org.cyclop.common.AppConfig; import org.cyclop.model.CqlQuery; import org.cyclop.model.CqlQueryType; import org.cyclop.model.QueryEntry; import org.cyclop.model.QueryFavourites; import org.cyclop.model.QueryHistory; import org.cyclop.model.UserIdentifier; import org.cyclop.model.exception.BeanValidationException; import org.cyclop.test.AbstractTestCase; import org.junit.Before; import org.junit.Test; /** @author Maciej Miklas */ public class TestFileStorage extends AbstractTestCase { @Inject private AppConfig config; @Inject private FileStorage storage; @Before public void setup() throws Exception { super.setup(); File histFolder = new File(config.fileStore.folder); histFolder.setWritable(true); assertTrue("History folder not writable:" + histFolder, histFolder.canWrite()); } @Test(expected = BeanValidationException.class) public void testRead_Validation() { storage.read(new UserIdentifier(), null); } @Test(expected = BeanValidationException.class) public void testRead_Validation_IncorrectUserIdentifier() { storage.read(new UserIdentifier(null), String.class); } @Test(expected = BeanValidationException.class) public void testStore_Validation() { storage.store(new UserIdentifier(), null); } @Test(expected = BeanValidationException.class) public void testStore_Validation_IncorrectUserIdentifier() { storage.store(new UserIdentifier(null), String.class); } @Test public void testSupported_OnWritableFolder() { assertTrue(storage.supported()); assertTrue(storage.checkSupported()); } @Test public void testSupported_OnReadOnlyFolder() { if (!unixOs) { return; } File histFolder = new File(config.fileStore.folder); if (histFolder.setWritable(false)) { assertTrue(storage.supported()); assertFalse(storage.checkSupported()); } } @Test public void testRead_FileNotFound() { assertFalse(storage.read(new UserIdentifier(UUID.randomUUID()), QueryHistory.class).isPresent()); } @Test public void testEmptyHistory() { QueryHistory hist = new QueryHistory(); assertEquals(0, hist.size()); try (QueryHistory.HistoryIterator iterator = hist.iterator()) { assertFalse(iterator.hasNext()); } CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable"); QueryEntry histEntry = new QueryEntry(query, 234); assertFalse(hist.contains(histEntry)); try { hist.iterator().next(); fail(); } catch (NoSuchElementException e) { // OK } } @Test public void testEmptyFavourites() { QueryFavourites hist = new QueryFavourites(); assertEquals(0, hist.size()); assertFalse(hist.copyAsSortedSet().iterator().hasNext()); CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable"); QueryEntry histEntry = new QueryEntry(query, 6456); assertFalse(hist.contains(histEntry)); try { hist.copyAsSortedSet().iterator().next(); fail(); } catch (NoSuchElementException e) { // OK } } @Test public void testCreateAndRead_SingleHistoryEntry() { UserIdentifier userId = new UserIdentifier(UUID.randomUUID()); QueryHistory newHistory = new QueryHistory(); CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable"); QueryEntry histEntry = new QueryEntry(query, 6645); newHistory.add(histEntry); storage.store(userId, newHistory); Optional<QueryHistory> readHistory = storage.read(userId, QueryHistory.class); assertNotNull(readHistory); assertEquals(1, readHistory.get().size()); int idx = 0; List<QueryEntry> histList = readHistory.get().copyAsList(); try (QueryHistory.HistoryIterator historyIterator = readHistory.get().iterator()) { assertTrue(historyIterator.hasNext()); QueryEntry readEntry = historyIterator.next(); assertEquals(histList.get(idx++), readEntry); assertEquals(query, readEntry.query); assertEquals(histEntry.executedOnUtc.toString(), readEntry.executedOnUtc.toString()); assertEquals(0, storage.getLockRetryCount()); } } @Test public void testCreateAndRead_SingleFavouritesEntry() { UserIdentifier userId = new UserIdentifier(UUID.randomUUID()); QueryFavourites newHistory = new QueryFavourites(); CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable"); QueryEntry favEntry = new QueryEntry(query, 234); newHistory.addWithSizeCheck(favEntry); storage.store(userId, newHistory); Optional<QueryFavourites> readHistory = storage.read(userId, QueryFavourites.class); assertNotNull(readHistory); assertEquals(1, readHistory.get().size()); assertTrue(readHistory.get().copyAsSortedSet().iterator().hasNext()); QueryEntry readEntry = readHistory.get().copyAsSortedSet().iterator().next(); assertEquals(query, readEntry.query); assertEquals(favEntry.executedOnUtc.toString(), readEntry.executedOnUtc.toString()); assertEquals(0, storage.getLockRetryCount()); } @Test public void testLimitFavourites() { UserIdentifier userId = new UserIdentifier(UUID.randomUUID()); QueryFavourites history = new QueryFavourites(); { for (int i = 0; i < 50; i++) { CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable where id=" + i); assertTrue(history.addWithSizeCheck(new QueryEntry(query, 234))); } assertEquals(50, history.size()); } checkFavLimitContent(history); { for (int i = 0; i < 10; i++) { CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTableA where id=" + i); assertFalse(history.addWithSizeCheck(new QueryEntry(query, 456))); } checkFavLimitContent(history); } { for (int i = 0; i < 20; i++) { CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable where id=" + i); assertTrue(history.addWithSizeCheck(new QueryEntry(query, 234))); } checkFavLimitContent(history); } { storage.store(userId, history); Optional<QueryFavourites> readHistory = storage.read(userId, QueryFavourites.class); checkFavLimitContent(readHistory.get()); checkFavLimitContent(history); } } private void checkFavLimitContent(QueryFavourites history) { Set<QueryEntry> fav = history.copyAsSortedSet(); Iterator<QueryEntry> favIt = fav.iterator(); assertEquals(50, fav.size()); assertEquals(50, history.size()); for (int i = 0; i < 50; i++) { assertTrue(favIt.hasNext()); CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable where id=" + i); assertTrue(history.contains(new QueryEntry(query, 7754))); assertTrue(history.contains(favIt.next())); } } private void testHistRange(QueryHistory history, int from, int to) { try (QueryHistory.HistoryIterator hit = history.iterator()) { for (int i = from; i >= to; i--) { assertTrue(hit.hasNext()); QueryEntry entry = hit.next(); assertTrue(history.contains(entry)); assertNotNull(entry.executedOnUtc); assertEquals("select * from MyTable1 where id=" + i, entry.query.part); } } } @Test public void testEvictHistory() { UserIdentifier userId = new UserIdentifier(UUID.randomUUID()); { QueryHistory history = new QueryHistory(); for (int i = 0; i < 600; i++) { CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable1 where id=" + i); history.add(new QueryEntry(query, 4563)); } assertEquals(500, history.size()); testHistRange(history, 599, 100); storage.store(userId, history); } { Optional<QueryHistory> history = storage.read(userId, QueryHistory.class); assertNotNull(history); assertEquals(500, history.get().size()); testHistRange(history.get(), 599, 100); for (int i = 0; i < 10; i++) { CqlQuery query = new CqlQuery(CqlQueryType.SELECT, "select * from MyTable2 where id=" + i); history.get().add(new QueryEntry(query, 567)); } storage.store(userId, history.get()); } { QueryHistory history = storage.read(userId, QueryHistory.class).get(); assertNotNull(history); assertEquals(500, history.size()); try (QueryHistory.HistoryIterator hit = history.iterator()) { for (int i = 9; i >= 0; i--) { assertTrue(hit.hasNext()); QueryEntry entry = hit.next(); assertTrue(history.contains(entry)); assertNotNull(entry.executedOnUtc); assertEquals("select * from MyTable2 where id=" + i, entry.query.part); } for (int i = 599; i > 110; i--) { assertTrue(hit.hasNext()); QueryEntry entry = hit.next(); assertTrue(history.contains(entry)); assertNotNull(entry.executedOnUtc); assertEquals("select * from MyTable1 where id=" + i, entry.query.part); } } } } }