Package org.kares.jruby

Source Code of org.kares.jruby.ServletWorkerManagerTest$ServletWorkerManagerImpl

/*
* Copyright (c) 2012 Karol Bucek
*
* 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.kares.jruby;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.servlet.ServletContext;

import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.builtin.IRubyObject;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
* @author kares <self_AT_kares_DOT_org>
*/
public class ServletWorkerManagerTest {

    private ServletWorkerManagerImpl subject;
   
    static class ServletWorkerManagerImpl extends ServletWorkerManager {
       
        ServletWorkerManagerImpl(final ServletContext context) {
            super(context);
        }
       
        final Collection<Ruby> runtimes = new ArrayList<Ruby>();
       
        @Override
        protected Ruby getRuntime() {
            RubyInstanceConfig config = new RubyInstanceConfig();
            config.setUpdateNativeENVEnabled(false);
            String path = new File("src/test/resources/ruby_stubs").getAbsolutePath();
            config.setLoadPaths( Collections.singletonList(path) );
           
            final Ruby runtime = Ruby.newInstance(config);
            runtimes.add(runtime);
            return runtime;
        }

        ThreadFactory threadFactory;
       
        @Override
        protected ThreadFactory newThreadFactory() {
            if ( threadFactory != null ) return threadFactory;
            return super.newThreadFactory();
        }
       
        void setThreadFactory(final ThreadFactory threadFactory) {
            this.threadFactory = threadFactory;
        }
       
    }
   
    @Before
    public void createSubject() {
        this.subject = new ServletWorkerManagerImpl( mockServletContext() );
    }

    @After
    public void tearDownRuntimes() {
        if (subject != null) {
            for (Ruby runtime : subject.runtimes) {
                runtime.tearDown(false);
            }
        }
    }
   
    @Test
    public void startupWarnsIfTheresNoWorker() {
        when( mockServletContext().getInitParameter( "jruby.worker" ) ).thenReturn( null );
       
        subject.startup();
       
        verify( servletContext ).getInitParameter( "jruby.worker" );
        verify( servletContext ).getInitParameter( "jruby.worker.script" );
       
        verify( mockServletContext(), atLeastOnce() ).log( contains("no worker script to execute") );
    }
   
    @Test
    public void startupShouldNotWarnIfThereIsAWorkerConfigured1() throws UnsupportedEncodingException {
        when( mockServletContext().getInitParameter( "jruby.worker" ) ).thenReturn( "Delayed::Job" );

        subject.startup();

        verify( mockServletContext(), never() ).log( contains("no worker script to execute") );
    }

    @Test
    public void startupShouldNotWarnIfThereIsAWorkerConfigured2() throws UnsupportedEncodingException {
        when( mockServletContext().getInitParameter( "jruby.worker" ) ).thenReturn( "delayed_job" );

        subject.startup();

        verify( mockServletContext(), never() ).log( contains("no worker script to execute") );
    }

    @Test
    public void startupShouldNotWarnIfThereIsAWorkerScriptConfigured() {
        when( mockServletContext().getInitParameter( "jruby.worker.script" ) ).thenReturn( "puts 'hello kares'" );

        subject.startup();

        verify( mockServletContext(), never() ).log( contains("no worker script to execute") );
    }

    @Test
    public void startupShouldNotWarnIfThereIsAValidWorkerScriptPathConfigured() throws UnsupportedEncodingException {
       
        when( mockServletContext().getInitParameter( "jruby.worker.script.path" ) ).thenReturn( "/path/worker.rb" );
        InputStream inputStream = new ByteArrayInputStream( "nil".getBytes("UTF-8") );
        when( mockServletContext().getResourceAsStream("/path/worker.rb") ).thenReturn( inputStream );

        subject.startup();

        verify( mockServletContext(), never() ).log( contains("no worker script to execute") );
    }

    @Test
    public void startASingleThreadByDefault() throws InterruptedException {
        final AtomicBoolean started = new AtomicBoolean(false);
        final Thread thread = new Thread() {

            @Override
            public synchronized void start() {
                started.set(true);
                super.start();
            }
           
        };
        WorkerThreadFactory threadFactory = mockWorkerThreadFactory();
        when( threadFactory.newThread( any(Runnable.class) ) ).thenReturn( thread );
        subject.setThreadFactory(threadFactory);
       
        when( mockServletContext().getInitParameter( "jruby.worker.script" ) ).thenReturn( "nil" );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_PRIORITY_KEY ) ).thenReturn( null );

        subject.startup();
       
        Thread.sleep(10);
       
        verify( threadFactory, times(1) ).newThread( any(Runnable.class) );
        assertTrue( started.get() ); //assertTrue( thread.isAlive() );
    }

    @Test
    public void startsDaemonThreadWithContextNamePrefixAndConfiguredPriority() {
        when( mockServletContext().getServletContextName() ).thenReturn( "TheTestApp" );
        when( mockServletContext().getInitParameter( "jruby.worker.script" ) ).thenReturn( "nil" );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_COUNT_KEY ) ).thenReturn( null );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_PRIORITY_KEY ) ).thenReturn( "7" );

        createSubject();
       
        final List<Thread> createdThreads = new ArrayList<Thread>();
        ThreadFactory threadFactory = subject.newThreadFactory();
        threadFactory = new MemoThreadFactory( threadFactory, createdThreads );
       
        subject.setThreadFactory(threadFactory);
       
        subject.startup();
       
        assertEquals( 1, createdThreads.size() );
        Thread thread = createdThreads.get(0);
        assertTrue( thread.isDaemon() );
        assertTrue( "thread-name: " + thread.getName(), thread.getName().startsWith("TheTestApp") );
        assertEquals( 7, thread.getPriority() );
    }

    @Test
    public void startsConfiguredAmountOfThreadsWithGivenPriority() throws UnsupportedEncodingException {
        when( mockServletContext().getInitParameter( "jruby.worker.script.path" ) ).thenReturn( "/path/worker.rb" );
        InputStream inputStream = new ByteArrayInputStream( "nil".getBytes("UTF-8") );
        when( mockServletContext().getResourceAsStream("/path/worker.rb") ).thenReturn( inputStream );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_COUNT_KEY ) ).thenReturn( "3" );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_PRIORITY_KEY ) ).thenReturn( "MIN" );

        createSubject();
       
        final List<Thread> createdThreads = new ArrayList<Thread>();
        ThreadFactory threadFactory = subject.newThreadFactory();
        threadFactory = new MemoThreadFactory( threadFactory, createdThreads );
       
        subject.setThreadFactory(threadFactory);
       
        subject.startup();

        assertEquals( 3, createdThreads.size() );
        for ( Thread thread : createdThreads ) {
            assertTrue( thread.isDaemon() );
            assertEquals( Thread.MIN_PRIORITY, thread.getPriority() );
        }
    }

    @Test
    public void stopsAllStartedThreads1() {
        when( mockServletContext().getServletContextName() ).thenReturn( "TheTestApp" );
        when( mockServletContext().getInitParameter( WorkerManager.SCRIPT_KEY ) ).thenReturn( "nil" );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_COUNT_KEY ) ).thenReturn( "2" );

        createSubject();
       
        final List<Thread> createdThreads = new ArrayList<Thread>();
        ThreadFactory threadFactory = subject.newThreadFactory();
        threadFactory = new MemoThreadFactory( threadFactory, createdThreads );
       
        subject.setThreadFactory(threadFactory);
       
        subject.startup();
       
        //Thread.yield();
       
        subject.shutdown();

        for ( Thread thread : createdThreads ) {
            assertFalse( thread.isAlive() );
        }
    }

    @Test
    public void stopsAllStartedThreads2() throws InterruptedException {
        when( mockServletContext().getInitParameter( WorkerManager.SCRIPT_KEY ) ).thenReturn( "sleep(0.1)" );
        when( mockServletContext().getInitParameter( WorkerManager.THREAD_COUNT_KEY ) ).thenReturn( "3" );

        createSubject();
       
        final List<Thread> createdThreads = new ArrayList<Thread>();
        ThreadFactory threadFactory = subject.newThreadFactory();
        threadFactory = new MemoThreadFactory( threadFactory, createdThreads );
       
        subject.setThreadFactory(threadFactory);

        subject.startup();
       
        Thread.sleep(500);
       
        subject.shutdown();

        for ( Thread thread : createdThreads ) {
            assertFalse( thread.isAlive() );
        }
    }

    @Test
    public void exportedItselfIntoTheRuntime() throws UnsupportedEncodingException {
        when( mockServletContext().getInitParameter( WorkerManager.SCRIPT_KEY ) ).thenReturn( "nil" );
       
        subject.setExported(true);
        subject.startup();

        RubyWorker worker = subject.workers.keySet().iterator().next();
        IRubyObject workerManagerProxy = worker.runtime.evalScriptlet("$worker_manager");
        assertNotNull("$worker_manager not exported", workerManagerProxy);
        Object workerManager = JavaEmbedUtils.rubyToJava(workerManagerProxy);
        assertEquals(subject, workerManager);
    }
   
    /**
     * =============================== Helpers ===============================
     */

    private WorkerThreadFactory workerThreadFactory;
   
    WorkerThreadFactory mockWorkerThreadFactory() {
        if (workerThreadFactory == null) {
            workerThreadFactory = mock(WorkerThreadFactory.class);
        }
        return workerThreadFactory;
    }

    private ServletContext servletContext;
   
    ServletContext mockServletContext() {
        if (servletContext == null) {
            servletContext = mock(ServletContext.class);
        }
        return servletContext;
    }
   
}
TOP

Related Classes of org.kares.jruby.ServletWorkerManagerTest$ServletWorkerManagerImpl

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.