org.lilyproject.process.test.DecoratorTest.java Source code

Java tutorial

Introduction

Here is the source code for org.lilyproject.process.test.DecoratorTest.java

Source

/*
 * Copyright 2012 NGDATA nv
 *
 * Licensed 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.lilyproject.process.test;

import java.io.File;
import java.util.IdentityHashMap;

import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.lilyproject.client.LilyClient;
import org.lilyproject.lilyservertestfw.LilyProxy;
import org.lilyproject.process.decorator.TestRepositoryDecoratorFactory;
import org.lilyproject.repository.api.FieldType;
import org.lilyproject.repository.api.LRepository;
import org.lilyproject.repository.api.LTable;
import org.lilyproject.repository.api.QName;
import org.lilyproject.repository.api.Record;
import org.lilyproject.repository.api.RecordType;
import org.lilyproject.repository.api.Scope;
import org.lilyproject.repository.api.TypeManager;
import org.lilyproject.repository.model.impl.RepositoryModelImpl;
import org.lilyproject.server.modules.repository.DecoratingRepositoryManager;
import org.lilyproject.server.modules.repository.RepositoryDecoratorChain;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.lilyproject.repository.model.api.RepositoryDefinition.RepositoryLifecycleState;

/**
 * Tests the repository decorator feature.
 *
 * <p>This test relies on test-decorator being installed in the local maven repository, hence
 * requires that the build is done with "mvn install".</p>
 */
public class DecoratorTest {

    @Test
    public void test() throws Exception {
        LilyProxy lilyProxy = createLilyProxy();

        LilyClient client = lilyProxy.getLilyServerProxy().getClient();

        RepositoryModelImpl repositoryModel = new RepositoryModelImpl(
                lilyProxy.getLilyServerProxy().getZooKeeper());
        repositoryModel.create("repo1");
        assertTrue(repositoryModel.waitUntilRepositoryInState("repo1", RepositoryLifecycleState.ACTIVE, 60000L));
        repositoryModel.create("repo2");
        assertTrue(repositoryModel.waitUntilRepositoryInState("repo2", RepositoryLifecycleState.ACTIVE, 60000L));
        repositoryModel.close();

        // Make a schema
        TypeManager typeMgr = client.getDefaultRepository().getTypeManager();

        QName field1 = new QName("ns", "f1");
        FieldType fieldType1 = typeMgr.newFieldType(typeMgr.getValueType("STRING"), field1, Scope.NON_VERSIONED);
        fieldType1 = typeMgr.createFieldType(fieldType1);

        QName field2 = new QName("ns", "f2");
        FieldType fieldType2 = typeMgr.newFieldType(typeMgr.getValueType("STRING"), field2, Scope.NON_VERSIONED);
        fieldType2 = typeMgr.createFieldType(fieldType2);

        QName typeName = new QName("ns", "rt1");
        RecordType recordType = typeMgr.newRecordType(typeName);
        recordType.addFieldTypeEntry(fieldType1.getId(), false);
        recordType.addFieldTypeEntry(fieldType2.getId(), false);
        recordType = typeMgr.createRecordType(recordType);

        DecoratingRepositoryManager repositoryMgr = (DecoratingRepositoryManager) lilyProxy.getLilyServerProxy()
                .getLilyServerTestingUtility().getRuntime().getModuleById("repository").getApplicationContext()
                .getBean("repositoryManager");
        IdentityHashMap<Object, Object> chains = new IdentityHashMap<Object, Object>();

        // Test the decorator is applied for each repository and each table
        for (String repositoryName : new String[] { "default", "repo1", "repo2" }) {
            LRepository repository = client.getRepository(repositoryName);

            repository.getTableManager().createTable("table1");
            repository.getTableManager().createTable("table2");

            for (String tableName : new String[] { "record", "table1", "table2" }) {
                LTable table = repository.getTable(tableName);
                Record record = table.newRecord();
                record.setRecordType(typeName);
                record.setField(field1, "foobar");
                record = table.create(record);
                assertEquals("foo", record.getField(field2));
                assertEquals("foo", table.read(record.getId()).getField(field2));

                // Test we can get access to our test decorator: this is something that is occasionally useful
                // in test cases to check certain conditions, e.g. if the decorator would have async side effects.
                RepositoryDecoratorChain chain = repositoryMgr.getRepositoryDecoratorChain(repositoryName,
                        tableName);
                assertNotNull(chain);
                assertNotNull(chain.getDecorator(TestRepositoryDecoratorFactory.NAME));
                chains.put(chain.getDecorator(TestRepositoryDecoratorFactory.NAME), null);
                assertEquals(2, chain.getEntries().size());
            }
        }

        // There should be one instance of the decorator created for each repository-table combination (that
        // was accessed)
        assertEquals(3 * 3, chains.size());

        // Check that if we ask the same table twice, we get the same instance (verifies cache works)
        assertTrue(client.getRepository("repo1").getTable("table1") == client.getRepository("repo1")
                .getTable("table1"));

        lilyProxy.stop();

        // Check each of the decorators was properly closed
        assertEquals(9, TestRepositoryDecoratorFactory.CLOSE_COUNT.get());
    }

    private static LilyProxy createLilyProxy() throws Exception {
        String basedir = System.getProperty("basedir");
        if (basedir == null) {
            basedir = System.getProperty("java.io.tmpdir");
        }

        // Temp dir where we will create plugin & conf stuff
        File tmpDir = new File(basedir + "/target/lily-test");

        String pluginDir = setupPluginsDirectory(tmpDir);
        System.setProperty("lily.plugin.dir", pluginDir);

        File customConfDir = setupConfDirectory(tmpDir);
        System.setProperty("lily.conf.dir", basedir + "/../server/conf");
        System.setProperty("lily.conf.customdir", customConfDir.getAbsolutePath());

        try {
            LilyProxy lilyProxy = new LilyProxy();
            lilyProxy.start();
            return lilyProxy;
        } finally {
            // Make sure it's properties won't be used by later-running tests
            System.getProperties().remove("lily.plugin.dir");
            System.getProperties().remove("lily.conf.dir");
            System.getProperties().remove("lily.conf.customdir");
        }
    }

    private static String setupPluginsDirectory(File tmpDir) throws Exception {
        File pluginDir = new File(tmpDir + "/plugins");

        // Delete it if it would already exist
        FileUtils.deleteDirectory(pluginDir);

        FileUtils.forceMkdir(pluginDir);

        File beforeRepoDir = new File(pluginDir, "load-before-repository");
        FileUtils.forceMkdir(beforeRepoDir);

        String projectVersion = System.getProperty("project.version");
        if (projectVersion == null) {
            throw new Exception("This test relies on a system property project.version being set. Probably you "
                    + "are running this test outside of Maven? Try adding -Dproject.version=...");
        }

        String wiringXml = "<wiring>\n" + "  <modules>\n"
                + "    <artifact id=\"test-decorator\" groupId=\"org.lilyproject\" artifactId=\"lily-test-decorator\" version=\""
                + projectVersion + "\">\n" + "    </artifact>\n" + "  </modules>\n" + "</wiring>";

        FileUtils.writeStringToFile(new File(beforeRepoDir, "testdecorator.xml"), wiringXml, "UTF-8");

        return pluginDir.getAbsolutePath();
    }

    private static File setupConfDirectory(File tmpDir) throws Exception {
        File confDir = new File(tmpDir + "/conf");

        File repoConfDir = new File(confDir, "repository");
        FileUtils.forceMkdir(repoConfDir);

        // Write configuration to activate the decorator
        String repositoryXml = "<repository xmlns:conf=\"http://lilyproject.org/configuration\" conf:inherit=\"shallow\">"
                + "<decorators><decorator>test-decorator</decorator></decorators>" + "</repository>";

        FileUtils.writeStringToFile(new File(repoConfDir, "repository.xml"), repositoryXml, "UTF-8");

        return confDir;
    }
}