/* * 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.apache.wicket.pageStore; import java.security.SecureRandom; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.wicket.versioning.InMemoryPageStore; import org.junit.Test; /** * Tests for {@link AsynchronousDataStore} */ public class AsynchronousDataStoreTest { // private static final IDataStore WRAPPED_DATA_STORE = new DiskDataStore("asyncDataStoreApp", new StoreSettings(null).getFileStoreFolder(), Bytes.kilobytes(1)); private static final IDataStore WRAPPED_DATA_STORE = new InMemoryPageStore(); /** the data store under test */ private static final IDataStore DATA_STORE = new AsynchronousDataStore(WRAPPED_DATA_STORE, 100); /** the data for each page */ private static final byte[] DATA = new byte[] { 1, 2, 3 }; /** the used jsessionid's */ private static final String[] SESSIONS = new String[] { "s1", "s2", "s3" }; /** the ids for the stored/removed pages */ private static final int[] PAGE_IDS = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; /** how many operations to execute */ private static final int EXECUTIONS = 10000; /** used to wait the executions */ private static final CountDownLatch LATCH = new CountDownLatch(EXECUTIONS); /** the execution types */ private static final Runnable[] TASKS = new Runnable[] { new StoreTask(), new GetTask(), new RemovePageInSessionTask(), new RemoveSessionTask() }; private static final SecureRandom RND = new SecureRandom(); /** * Executes random mutator and accessor operations on {@link AsynchronousDataStore} validating * that the used data structures can be used simultaneously. * * @throws Exception */ @Test public void randomOperations() throws Exception { ExecutorService executorService = Executors.newFixedThreadPool(50); for (int i = 0; i < EXECUTIONS; i++) { Runnable task = TASKS[RND.nextInt(TASKS.length)]; executorService.submit(task); } LATCH.await(); executorService.shutdown(); DATA_STORE.destroy(); } private static abstract class AbstractTask implements Runnable { protected abstract void r(); @Override public void run() { try { r(); } finally { LATCH.countDown(); } } protected String getSessionId() { return SESSIONS[RND.nextInt(SESSIONS.length)]; } protected int getPageId() { return PAGE_IDS[RND.nextInt(PAGE_IDS.length)]; } } private static class StoreTask extends AbstractTask { @Override public void r() { DATA_STORE.storeData(getSessionId(), getPageId(), DATA); } } private static class GetTask extends AbstractTask { @Override public void r() { DATA_STORE.getData(getSessionId(), getPageId()); } } private static class RemovePageInSessionTask extends AbstractTask { @Override public void r() { DATA_STORE.removeData(getSessionId(), getPageId()); } } private static class RemoveSessionTask extends AbstractTask { @Override public void r() { DATA_STORE.removeData(getSessionId()); } } }