com.netflix.nicobar.cassandra.CassandraArchiveRepositoryTest.java Source code

Java tutorial

Introduction

Here is the source code for com.netflix.nicobar.cassandra.CassandraArchiveRepositoryTest.java

Source

/*
 * Copyright 2013 Netflix, Inc.
 *
 *      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 com.netflix.nicobar.cassandra;

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import org.apache.commons.io.IOUtils;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.model.Row;
import com.netflix.astyanax.model.Rows;
import com.netflix.nicobar.cassandra.CassandraArchiveRepository.Columns;
import com.netflix.nicobar.core.archive.JarScriptArchive;
import com.netflix.nicobar.core.archive.ModuleId;
import com.netflix.nicobar.core.archive.ScriptModuleSpec;

/**
 * Tests for {@link CassandraArchiveRepository}
 * @author Vasanth Asokan
 */
public class CassandraArchiveRepositoryTest {

    /**
     * Metadata for test resources found in test/resource
     */
    public static enum TestResource {
        TEST_HELLOWORLD_JAR("helloworld", "testmodules/helloworld.jar");

        private final ModuleId moduleId;
        private final String resourcePath;

        private TestResource(String moduleId, String resourcePath) {
            this.moduleId = ModuleId.create(moduleId);
            this.resourcePath = resourcePath;
        }

        /**
         * @return the expected moduleId after this is converted to a archive
         */
        public ModuleId getModuleId() {
            return moduleId;
        }

        /**
         * @return path name suitable for passing to {@link ClassLoader#getResource(String)}
         */
        public String getResourcePath() {
            return resourcePath;
        }
    }

    private CassandraArchiveRepository repository;
    private Path testArchiveJarFile;
    private CassandraGateway gateway;
    private CassandraArchiveRepositoryConfig config;

    @BeforeClass
    public void setup() throws Exception {
        gateway = mock(CassandraGateway.class);
        Keyspace mockKeyspace = mock(Keyspace.class);
        when(mockKeyspace.getKeyspaceName()).thenReturn("testKeySpace");

        when(gateway.getKeyspace()).thenReturn(mockKeyspace);
        when(gateway.getColumnFamily()).thenReturn("testColumnFamily");

        config = new BasicCassandraRepositoryConfig.Builder(gateway).setRepositoryId("TestRepo")
                .setArchiveOutputDirectory(Files.createTempDirectory(this.getClass().getSimpleName() + "_"))
                .build();
        repository = new CassandraArchiveRepository(config);

        URL testJarUrl = getClass().getClassLoader()
                .getResource(TestResource.TEST_HELLOWORLD_JAR.getResourcePath());
        if (testJarUrl == null) {
            fail("Couldn't locate " + TestResource.TEST_HELLOWORLD_JAR.getResourcePath());
        }
        testArchiveJarFile = Files.createTempFile(TestResource.TEST_HELLOWORLD_JAR.getModuleId().toString(),
                ".jar");
        InputStream inputStream = testJarUrl.openStream();
        Files.copy(inputStream, testArchiveJarFile, StandardCopyOption.REPLACE_EXISTING);
        IOUtils.closeQuietly(inputStream);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Test
    public void testInsertArchive() throws IOException {
        JarScriptArchive jarArchive = new JarScriptArchive.Builder(testArchiveJarFile).build();
        repository.insertArchive(jarArchive);

        Map<String, Object> columns = new HashMap<String, Object>();
        Path jarFilePath;
        try {
            jarFilePath = Paths.get(jarArchive.getRootUrl().toURI());
        } catch (URISyntaxException e) {
            throw new IOException(e);
        }
        ScriptModuleSpec moduleSpec = jarArchive.getModuleSpec();
        String serialized = config.getModuleSpecSerializer().serialize(moduleSpec);
        byte[] jarBytes = Files.readAllBytes(jarFilePath);
        columns.put(Columns.shard_num.name(), repository.calculateShardNum(moduleSpec.getModuleId()));
        columns.put(Columns.last_update.name(), jarArchive.getCreateTime());
        columns.put(Columns.archive_content.name(), jarBytes);
        columns.put(Columns.archive_content_hash.name(), repository.calculateHash(jarBytes));
        columns.put(Columns.module_spec.name(), serialized);

        ArgumentCaptor<String> argument1 = ArgumentCaptor.forClass(String.class);
        ArgumentCaptor<Map> argument2 = ArgumentCaptor.forClass(Map.class);
        verify(gateway).upsert(argument1.capture(), argument2.capture());

        assertEquals(moduleSpec.getModuleId().toString(), argument1.getValue());
        Map columnMap = argument2.getValue();
        assertEquals(repository.calculateShardNum(moduleSpec.getModuleId()),
                columnMap.get(Columns.shard_num.name()));
        assertTrue(Arrays.equals(jarBytes, (byte[]) columnMap.get(Columns.archive_content.name())));
        assertTrue(Arrays.equals(repository.calculateHash(jarBytes),
                (byte[]) columnMap.get(Columns.archive_content_hash.name())));
        assertEquals(serialized, (String) columnMap.get(Columns.module_spec.name()));
        assertEquals(jarArchive.getCreateTime(), (long) columnMap.get(Columns.last_update.name()));
    }

    @Test(expectedExceptions = UnsupportedOperationException.class)
    public void testArchiveWithDeploySpecs() throws IOException {
        JarScriptArchive jarArchive = new JarScriptArchive.Builder(testArchiveJarFile).build();
        repository.insertArchive(jarArchive, null);
    }

    @Test(expectedExceptions = UnsupportedOperationException.class)
    public void testGetView() throws IOException {
        repository.getView("");
    }

    @Test
    public void testDeleteArchive() throws IllegalArgumentException, IOException {
        repository.deleteArchive(ModuleId.fromString("testModule.v3"));
        verify(gateway).deleteRow("testModule.v3");
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testGetRows() throws Exception {
        EnumSet<Columns> columns = EnumSet.of(Columns.module_id, Columns.module_name);
        Rows<String, String> mockRows = mock(Rows.class);
        Row<String, String> row1 = mock(Row.class);
        Row<String, String> row2 = mock(Row.class);
        List<Row<String, String>> rowList = Arrays.asList(row1, row2);

        when(mockRows.iterator()).thenReturn(rowList.iterator());

        FutureTask<Rows<String, String>> future = new FutureTask<Rows<String, String>>(new Runnable() {
            @Override
            public void run() {
            }
        }, mockRows);
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.execute(future);
        when(gateway.selectAsync(anyString())).thenReturn(future);

        repository.getRows(columns);
        List<String> selectList = new ArrayList<String>();
        for (int shardNum = 0; shardNum < config.getShardCount(); shardNum++) {
            selectList.add(repository.generateSelectByShardCql(columns, shardNum));
        }

        InOrder inOrder = inOrder(gateway);
        for (int shardNum = 0; shardNum < config.getShardCount(); shardNum++) {
            inOrder.verify(gateway).selectAsync(selectList.get(shardNum));
        }
    }

    @Test
    public void testGetArchiveUpdateTimes() {
        // TODO: Fill out test.
    }

    @Test
    public void testGetArchiveSummaries() {
        // TODO: Fill out test.
    }

    @Test
    public void testGetRepositorySummary() throws Exception {
        // TODO: Fill out test.
    }

    @Test
    public void testGetScriptArchives() {
        // TODO: Fill out test.
    }

}