Package org.apache.ace.client.repositoryuseradmin.impl

Source Code of org.apache.ace.client.repositoryuseradmin.impl.RepositoryUserAdminSerializationTest$MockCachedRepository

/*
* 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.ace.client.repositoryuseradmin.impl;

import static org.apache.ace.test.utils.TestUtils.UNIT;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import org.apache.ace.range.SortedRangeSet;
import org.apache.ace.repository.ext.CachedRepository;
import org.apache.ace.test.utils.TestUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.log.LogService;
import org.osgi.service.prefs.Preferences;
import org.osgi.service.prefs.PreferencesService;
import org.osgi.service.useradmin.Group;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class RepositoryUserAdminSerializationTest {

    private RepositoryUserAdminImpl m_impl;

    private MockCachedRepository m_cachedRepository;

    @BeforeMethod(alwaysRun = true)
    public void setUp() {
        m_impl = new RepositoryUserAdminImpl();
        TestUtils.configureObject(m_impl, BundleContext.class, TestUtils.createMockObjectAdapter(BundleContext.class, new Object() {
            @SuppressWarnings("unused")
            public Filter createFilter(String s) throws InvalidSyntaxException {
                return FrameworkUtil.createFilter(s);
            }
        }));

        // We configure the CachedRepository ourselves, so there is no need to login
        m_cachedRepository = new MockCachedRepository();
        TestUtils.configureObject(m_impl, CachedRepository.class, m_cachedRepository);
        TestUtils.configureObject(m_impl, PreferencesService.class);
        TestUtils.configureObject(m_impl, LogService.class);
        TestUtils.configureObject(m_impl, Preferences.class); // A Preferences is cached for storing the version.
    }

    @SuppressWarnings("unchecked")
    @Test(groups = { UNIT })
    public void testRepositoryUserAdminSerialization() throws Exception {
        // Create some data
        User user = (User) m_impl.createRole("me", Role.USER);
        user.getProperties().put("fullname", "Mr. M. Me");
        user.getCredentials().put("password", "swordfish");
        user.getCredentials().put("certificate", new byte[] {'4', '2'});
        Group group = (Group) m_impl.createRole("myGroup", Role.GROUP);
        group.getProperties().put("description", "One group to rule them all.");
        group.addMember(user);

        // Write it to the store
        new Thread("RepositoryUserAdmin committer") {
            @Override
            public void run() {
                try {
                    m_impl.commit();
                }
                catch (Exception e) {
                    System.err.println("Error writing data");
                    e.printStackTrace(System.err);
                }
            }
        }.start();

        // wait for impl to be ready, and retrieve what he has written
        Object[] request  = m_cachedRepository.getRequest(true);
        assert request[0].equals("writeLocal");
        InputStream input = (InputStream) request[1];
        request = m_cachedRepository.getRequest(true);
        assert request[0].equals("commit");

        String data1 = getInputStreamAsString(input);

        // alter the contents
        m_impl.createRole("otherme", Role.USER);
        m_impl.removeRole("myGroup");

        m_cachedRepository.addResponse(new ByteArrayInputStream(data1.getBytes()));

        final Semaphore sem = new Semaphore(0);

        // make impl read what it has just written
        new Thread("RepositoryUserAdmin committer") {
            @Override
            public void run() {
                try {
                    m_impl.checkout();
                }
                catch (Exception e) {
                    System.err.println("Error reading data");
                    e.printStackTrace(System.err);
                }
                sem.release();
            }
        }.start();

        // wait for the reading to be done
        sem.tryAcquire(5, TimeUnit.SECONDS);

        request = m_cachedRepository.getRequest(true);
        assert request[0].equals("checkout");

        // inspect the current contents of impl
        Role[] roles = m_impl.getRoles(null);
        assert roles.length == 2 : "Found " + roles.length + " roles in stead of 2.";
        for (Role role : roles) {
            if (role.equals(user)) {
                assert user.hasCredential("password", "swordfish");
                assert user.hasCredential("certificate", new byte[] {'4', '2'});
            }
            else if (role.equals(group)) {
                assert ((Group) role).getMembers().length == 1 : "We expect one member in the group in stream of " + ((Group) role).getMembers().length;
                assert ((Group) role).getMembers()[0].equals(user);
            }
            else {
                assert false : "Found an unknown role: " + role.toString() + " (" + role.getName() + ")";
            }
        }
    }

    @Test(groups = { UNIT })
    public void testCircularDependency() throws Exception {
        Group g1 = (Group) m_impl.createRole("group1", Role.GROUP);
        Group g2 = (Group) m_impl.createRole("group2", Role.GROUP);
        g1.addMember(g2);
        g2.addMember(g1);

        try {
            m_impl.commit();
            assert false : "There is a circular dependency, this should be detected and reason for failure.";
        }
        catch (IllegalArgumentException iae) {
            // expected
        }
    }

    /**
     * A mock cached repository, used for checking calls and staging responses to impl.
     */
    private static class MockCachedRepository extends MockResponder implements CachedRepository {

        public InputStream checkout(boolean fail) throws IOException {
            handleRequest("checkout", fail);
            return (InputStream) handleResponse();
        }

        public boolean commit() throws IOException {
            handleRequest("commit");
            return false;
        }

        public InputStream getLocal(boolean fail) throws IOException {
            return null;
        }

        public long getMostRecentVersion() {
            return 0;
        }

        public boolean isCurrent() throws IOException {
            return false;
        }

        public boolean revert() throws IOException {
            return false;
        }

        public void writeLocal(InputStream data) throws IOException {
            handleRequest("writeLocal", data);
        }

        public InputStream checkout(long version) throws IOException, IllegalArgumentException {
            return null;
        }

        public boolean commit(InputStream data, long fromVersion) throws IOException, IllegalArgumentException {
            return false;
        }

        public SortedRangeSet getRange() throws IOException {
            return null;
        }

    }

    /**
     * Base class responder, used for inspecting calls and staging responses.
     */
    private static class MockResponder {
        protected BlockingQueue<Object> m_responses = new LinkedBlockingQueue<Object>();
        protected BlockingQueue<Object[]> m_requests = new LinkedBlockingQueue<Object[]>();

        public void addResponse(Object response) {
            m_responses.add(response);
        }

        public Object[] getRequest(boolean wait) {
            if (wait) {
                Object[] result = null;
                try {
                    result = m_requests.poll(5, TimeUnit.SECONDS);
                }
                catch (Exception e) {
                    System.err.println("Interrupted while waiting for blocked queue.");
                    Thread.currentThread().interrupt();
                }
                if (result == null) {
                    assert false : "Even after 5 seconds, no request was ready for us.";
                }
                return result;
            }
            else {
                return m_requests.poll();
            }
        }

        public boolean moreRequests() {
            return !m_requests.isEmpty();
        }

        protected void handleRequest(Object... objs) {
            m_requests.add(objs);
        }

        protected Object handleResponse() {
            return m_responses.poll();
        }
    }

    /**
     * Helper method that gets the contents of a stream into a single string.
     */
    private static String getInputStreamAsString(InputStream in) throws IOException {
        char[] buf = new char[1];
        StringBuilder found = new StringBuilder();
        InputStreamReader bf = new InputStreamReader(in);
        while (bf.read(buf) > 0) {
            found.append(buf);
        }
        bf.close();
        return found.toString();
    }

}
TOP

Related Classes of org.apache.ace.client.repositoryuseradmin.impl.RepositoryUserAdminSerializationTest$MockCachedRepository

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.