com.vmware.admiral.adapter.docker.service.SystemImageRetrievalManagerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.admiral.adapter.docker.service.SystemImageRetrievalManagerTest.java

Source

/*
 * Copyright (c) 2016-2017 VMware, Inc. All Rights Reserved.
 *
 * This product is licensed to you under the Apache License, Version 2.0 (the "License").
 * You may not use this product except in compliance with the License.
 *
 * This product may include a number of subcomponents with separate copyright notices
 * and license terms. Your use of these subcomponents is subject to the terms and
 * conditions of the subcomponent's license, as noted in the LICENSE file.
 */

package com.vmware.admiral.adapter.docker.service;

/*
 *
 * This product is licensed to you under the Apache License, Version 2.0 (the "License").
 * You may not use this product except in compliance with the License.
 *
 * This product may include a number of subcomponents with separate copyright notices
 * and license terms. Your use of these subcomponents is subject to the terms and
 * conditions of the subcomponent's license, as noted in the LICENSE file.
 */
import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.vmware.admiral.adapter.common.AdapterRequest;
import com.vmware.admiral.common.test.BaseTestCase;
import com.vmware.admiral.common.util.FileUtil;
import com.vmware.admiral.host.HostInitCommonServiceConfig;
import com.vmware.admiral.service.common.ConfigurationService.ConfigurationFactoryService;
import com.vmware.admiral.service.common.ConfigurationService.ConfigurationState;
import com.vmware.xenon.common.Operation;
import com.vmware.xenon.common.StatelessService;
import com.vmware.xenon.common.UriUtils;
import com.vmware.xenon.common.test.TestContext;

public class SystemImageRetrievalManagerTest extends BaseTestCase {

    private static final String TEST_IMAGE = "testimage.tar";
    private static final String TEST_IMAGE_RES = "testimageRes.tar";

    private SystemImageRetrievalManager retrievalManager;

    @Before
    public void setup() {
        retrievalManager = new SystemImageRetrievalManager(host);
    }

    @Override
    protected boolean getPeerSynchronizationEnabled() {
        return true;
    }

    @Test
    public void testGetFromUserResources() throws Throwable {
        Path testXenonImagesPath = Files.createTempDirectory("test-xenon-images");

        HostInitCommonServiceConfig.startServices(host);
        waitForServiceAvailability(ConfigurationFactoryService.SELF_LINK);
        waitForServiceAvailability(UriUtils.buildUriPath(UriUtils
                .buildUriPath(ConfigurationFactoryService.SELF_LINK, FileUtil.USER_RESOURCES_PATH_VARIABLE)));

        // Set expected configuration
        ConfigurationState config = new ConfigurationState();
        config.documentSelfLink = UriUtils.buildUriPath(ConfigurationFactoryService.SELF_LINK,
                FileUtil.USER_RESOURCES_PATH_VARIABLE);
        config.key = FileUtil.USER_RESOURCES_PATH_VARIABLE;
        config.value = testXenonImagesPath.toAbsolutePath().toString();

        doPost(config, ConfigurationFactoryService.SELF_LINK);

        File imageDir = new File(UriUtils.buildUriPath(testXenonImagesPath.toString(),
                SystemImageRetrievalManager.SYSTEM_IMAGES_PATH));
        imageDir.mkdir();

        byte[] content = IOUtils
                .toByteArray(Thread.currentThread().getContextClassLoader().getResourceAsStream(TEST_IMAGE));
        // Basically, rename it so it must be loaded from user resources for sure
        File tmpFile = new File(UriUtils.buildUriPath(imageDir.getAbsolutePath(), TEST_IMAGE_RES));
        tmpFile.createNewFile();
        try (OutputStream os = new FileOutputStream(tmpFile)) {
            os.write(content);
        }

        AdapterRequest req = new AdapterRequest();
        req.resourceReference = host.getUri();

        AtomicReference<byte[]> retrievedImageRef = new AtomicReference<>();

        TestContext ctx = testCreate(1);
        retrievalManager.retrieveAgentImage(TEST_IMAGE_RES, req, (image) -> {
            retrievedImageRef.set(image);
            ctx.completeIteration();
        });

        ctx.await();

        byte[] image = retrievedImageRef.get();
        Assert.assertEquals("Unexpected content", new String(content), new String(image));
    }

    @Test
    public void testGetFromUserResourcesConcurrent() throws Throwable {
        Path testXenonImagesPath = Files.createTempDirectory("test-xenon-images");

        // Set expected configuration
        ConfigurationState config = new ConfigurationState();
        config.documentSelfLink = UriUtils.buildUriPath(ConfigurationFactoryService.SELF_LINK,
                FileUtil.USER_RESOURCES_PATH_VARIABLE);
        config.key = FileUtil.USER_RESOURCES_PATH_VARIABLE;
        config.value = testXenonImagesPath.toAbsolutePath().toString();

        MockConfigurationService mockConfigurationService = new MockConfigurationService(config);
        host.startService(Operation.createPost(UriUtils.buildUri(host, UriUtils
                .buildUriPath(ConfigurationFactoryService.SELF_LINK, FileUtil.USER_RESOURCES_PATH_VARIABLE))),
                mockConfigurationService);

        File imageDir = new File(UriUtils.buildUriPath(testXenonImagesPath.toString(),
                SystemImageRetrievalManager.SYSTEM_IMAGES_PATH));
        imageDir.mkdir();

        byte[] content = IOUtils
                .toByteArray(Thread.currentThread().getContextClassLoader().getResourceAsStream(TEST_IMAGE));
        // Basically, rename it so it must be loaded from user resources for sure
        File tmpFile = new File(UriUtils.buildUriPath(imageDir.getAbsolutePath(), TEST_IMAGE_RES));
        tmpFile.createNewFile();
        try (OutputStream os = new FileOutputStream(tmpFile)) {
            os.write(content);
        }

        AdapterRequest req = new AdapterRequest();
        req.resourceReference = host.getUri();

        List<byte[]> retrievedImages = new ArrayList<>();

        int numberOfRequests = 4;

        TestContext ctx = testCreate(numberOfRequests);

        final ExecutorService threadPool = Executors.newFixedThreadPool(numberOfRequests);

        List<Callable<Void>> callables = new ArrayList<>();
        for (int i = 0; i < numberOfRequests; i++) {
            callables.add(() -> {
                host.log("Calling retrieveAgentImage");
                retrievalManager.retrieveAgentImage(TEST_IMAGE_RES, req, (image) -> {
                    retrievedImages.add(image);
                    ctx.completeIteration();
                });
                return null;
            });
        }

        host.log("Invoke all callables to retrieveAgentImage");
        threadPool.invokeAll(callables);

        ctx.await();

        // Assert that all callbacks were called
        assertEquals(numberOfRequests, retrievedImages.size());
        for (int i = 0; i < numberOfRequests; i++) {
            byte[] image = retrievedImages.get(i);
            Assert.assertEquals("Unexpected content", new String(content), new String(image));
        }

        // Assert that service was called only once for all concurrent requests
        assertEquals(1, mockConfigurationService.getNumberOfRequests());
    }

    @Test
    public void testGetFromClassPath() throws Throwable {
        Path testXenonImagesPath = Files.createTempDirectory("test-xenon-images");

        HostInitCommonServiceConfig.startServices(host);
        waitForServiceAvailability(ConfigurationFactoryService.SELF_LINK);
        waitForServiceAvailability(UriUtils.buildUriPath(UriUtils
                .buildUriPath(ConfigurationFactoryService.SELF_LINK, FileUtil.USER_RESOURCES_PATH_VARIABLE)));

        // Set expected configuration
        ConfigurationState config = new ConfigurationState();
        config.documentSelfLink = UriUtils.buildUriPath(ConfigurationFactoryService.SELF_LINK,
                FileUtil.USER_RESOURCES_PATH_VARIABLE);
        config.key = FileUtil.USER_RESOURCES_PATH_VARIABLE;
        config.value = testXenonImagesPath.toAbsolutePath().toString();

        doPost(config, ConfigurationFactoryService.SELF_LINK);

        File imageDir = new File(UriUtils.buildUriPath(testXenonImagesPath.toString(),
                SystemImageRetrievalManager.SYSTEM_IMAGES_PATH));
        imageDir.mkdir();

        byte[] content = IOUtils
                .toByteArray(Thread.currentThread().getContextClassLoader().getResourceAsStream(TEST_IMAGE));

        AdapterRequest req = new AdapterRequest();
        req.resourceReference = host.getUri();

        AtomicReference<byte[]> retrievedImageRef = new AtomicReference<>();

        TestContext ctx = testCreate(1);
        retrievalManager.retrieveAgentImage(TEST_IMAGE, req, (image) -> {
            retrievedImageRef.set(image);
            ctx.completeIteration();
        });

        ctx.await();

        byte[] image = retrievedImageRef.get();
        Assert.assertEquals("Unexpected content", new String(content), new String(image));
    }

    private class MockConfigurationService extends StatelessService {

        private int numberOfRequests = 0;
        private ConfigurationState state;

        public MockConfigurationService(ConfigurationState state) {
            this.state = state;
        }

        @Override
        public void handleGet(Operation get) {
            host.log("MockConfigurationService handles get. Current number of requests %s", numberOfRequests);
            numberOfRequests++;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }
            host.log("MockConfigurationService completes get. Current number of requests %s", numberOfRequests);
            get.setBody(state).complete();
        }

        public int getNumberOfRequests() {
            return numberOfRequests;
        }
    }
}