org.jahia.bin.ErrorFileDumperTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jahia.bin.ErrorFileDumperTest.java

Source

/**
 * ==========================================================================================
 * =                   JAHIA'S DUAL LICENSING - IMPORTANT INFORMATION                       =
 * ==========================================================================================
 *
 *                                 http://www.jahia.com
 *
 *     Copyright (C) 2002-2017 Jahia Solutions Group SA. All rights reserved.
 *
 *     THIS FILE IS AVAILABLE UNDER TWO DIFFERENT LICENSES:
 *     1/GPL OR 2/JSEL
 *
 *     1/ GPL
 *     ==================================================================================
 *
 *     IF YOU DECIDE TO CHOOSE THE GPL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS:
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *     2/ JSEL - Commercial and Supported Versions of the program
 *     ===================================================================================
 *
 *     IF YOU DECIDE TO CHOOSE THE JSEL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS:
 *
 *     Alternatively, commercial and supported versions of the program - also known as
 *     Enterprise Distributions - must be used in accordance with the terms and conditions
 *     contained in a separate written agreement between you and Jahia Solutions Group SA.
 *
 *     If you are unsure which license is appropriate for your use,
 *     please contact the sales department at sales@jahia.com.
 */
package org.jahia.bin;

import org.apache.commons.io.FileUtils;
import org.jahia.bin.errors.ErrorFileDumper;
import org.jahia.settings.SettingsBean;
import org.jahia.utils.RequestLoadAverage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.util.StopWatch;

import javax.servlet.http.HttpServletRequest;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;

/**
 * Test unit for error file dumper sub system.
 */
public class ErrorFileDumperTest {

    private final long LOOP_COUNT = 1000L;
    private final long THREAD_COUNT = 200;
    private Set<Thread> threadSet = new HashSet<Thread>();
    private static File todaysDirectory;

    private transient static Logger logger = org.slf4j.LoggerFactory.getLogger(ErrorFileDumperTest.class);

    @BeforeClass
    public static void oneTimeSetUp() throws Exception {
        Date now = new Date();
        todaysDirectory = new File(SettingsBean.getErrorDir(), ErrorFileDumper.DATE_FORMAT_DIRECTORY.format(now));
        logger.info("Error directory is " + todaysDirectory.getAbsolutePath());
        new SettingsBean(null, new Properties(), Collections.<String>emptyList());
    }

    @AfterClass
    public static void oneTimeTearDown() throws Exception {
        FileUtils.deleteDirectory(todaysDirectory);
        if (RequestLoadAverage.getInstance() != null) {
            RequestLoadAverage.getInstance().stop();
        }
    }

    @After
    public void tearDown() throws Exception {
        FileUtils.deleteDirectory(todaysDirectory);
    }

    @Test
    public void testDumperActivation() throws InterruptedException {

        logger.info("Starting testDumperInSequence test...");

        ErrorFileDumper.start();

        logger.info("Activating Error file dumping...");
        ErrorFileDumper.setFileDumpActivated(true);

        File[] files = todaysDirectory.listFiles();
        int fileCountBeforeTest = (files == null ? 0 : files.length);

        generateExceptions();

        Thread.sleep(5000);

        files = todaysDirectory.listFiles();
        int fileCountAfterTest = (files == null ? 0 : files.length);
        Assert.assertTrue("File count after test should be higher but it is not",
                (fileCountAfterTest > fileCountBeforeTest));

        logger.info("De-activating Error file dumping...");

        ErrorFileDumper.setFileDumpActivated(false);

        files = todaysDirectory.listFiles();
        fileCountBeforeTest = (files == null ? 0 : files.length);

        generateExceptions();

        Thread.sleep(5000);

        files = todaysDirectory.listFiles();
        fileCountAfterTest = (files == null ? 0 : files.length);

        Assert.assertEquals("File count after test should be the same as before", fileCountBeforeTest,
                fileCountAfterTest);

        ErrorFileDumper.shutdown(10000L);

    }

    @Test
    public void testHighLoadDeactivation() throws InterruptedException {

        logger.info("Starting testHighLoadDeactivation test...");

        RequestLoadAverage.RequestCountProvider requestCountProvider = new RequestLoadAverage.RequestCountProvider() {
            public long getRequestCount() {
                return 100;
            }
        };

        RequestLoadAverage requestLoadAverage = new RequestLoadAverage("requestLoadAverage", requestCountProvider);
        requestLoadAverage.start();
        logger.info("Waiting for load average to reach 10...");
        while (requestLoadAverage.getOneMinuteLoad() < 10.0) {
            Thread.sleep(500);
        }

        StopWatch stopWatch = new StopWatch("testHighLoadDeactivation");
        stopWatch.start(Thread.currentThread().getName() + " generating error dumps");

        int fileCountBeforeTest = 0;
        if (todaysDirectory.exists()) {
            File[] files = todaysDirectory.listFiles();
            fileCountBeforeTest = (files == null ? 0 : files.length);
        }

        ErrorFileDumper.setHighLoadBoundary(10.0);
        ErrorFileDumper.start();

        generateExceptions();

        stopWatch.stop();
        long totalTime = stopWatch.getTotalTimeMillis();
        double averageTime = ((double) totalTime) / ((double) LOOP_COUNT);
        logger.info("Milliseconds per exception = " + averageTime);
        logger.info(stopWatch.prettyPrint());

        ErrorFileDumper.shutdown(10000L);

        RequestLoadAverage.getInstance().stop();

        int fileCountAfterTest = 0;
        if (todaysDirectory.exists()) {
            File[] files = todaysDirectory.listFiles();
            fileCountAfterTest = (files == null ? 0 : files.length);
        }

        Assert.assertEquals("File count should stay the same because high load deactivates file dumping !",
                fileCountBeforeTest, fileCountAfterTest);

        requestLoadAverage = new RequestLoadAverage("requestLoadAverage");
    }

    @Test
    public void testDumperInSequence() throws InterruptedException {

        logger.info("Starting testDumperInSequence test...");

        StopWatch stopWatch = new StopWatch("testDumperInSequence");
        stopWatch.start(Thread.currentThread().getName() + " generating error dumps");

        ErrorFileDumper.start();

        generateExceptions();

        stopWatch.stop();
        long totalTime = stopWatch.getTotalTimeMillis();
        double averageTime = ((double) totalTime) / ((double) LOOP_COUNT);
        logger.info("Milliseconds per exception = " + averageTime);
        logger.info(stopWatch.prettyPrint());

        ErrorFileDumper.shutdown(10000L);

        Assert.assertTrue("Error dump directory does not exist !", todaysDirectory.exists());
        Assert.assertTrue("Error dump directory should have error files in it !",
                todaysDirectory.listFiles().length > 0);
    }

    @Test
    public void testDumpErrorsToFilesSetting() throws InterruptedException {
        logger.info("Starting testDumpErrorsToFilesSetting test...");

        StopWatch stopWatch = new StopWatch("testDumpErrorsToFilesSetting");
        stopWatch.start(Thread.currentThread().getName() + " generating error dumps");

        ErrorFileDumper.start();
        ErrorFileDumper.setFileDumpActivated(false);

        generateExceptions();

        stopWatch.stop();
        long totalTime = stopWatch.getTotalTimeMillis();
        double averageTime = ((double) totalTime) / ((double) LOOP_COUNT);
        logger.info("Milliseconds per exception = " + averageTime);
        logger.info(stopWatch.prettyPrint());

        ErrorFileDumper.shutdown(10000L);

        SettingsBean.getInstance().setDumpErrorsToFiles(true);
        Assert.assertFalse("Error dump directory should not exist !", todaysDirectory.exists());
    }

    @Test
    public void testDumperInParallel() throws IOException, InterruptedException {

        logger.info("Starting testDumperInParallel test...");

        StopWatch stopWatch = new StopWatch("testDumperInParallel");
        stopWatch.start(Thread.currentThread().getName() + " generating error dumps");

        ErrorFileDumper.start();

        threadSet.clear();

        for (int i = 0; i < THREAD_COUNT; i++) {
            Thread newThread = new Thread(new Runnable() {

                public void run() {
                    generateExceptions();
                }
            }, "ErrorFileDumperTestThread" + i);
            threadSet.add(newThread);
            newThread.start();
        }

        logger.info("Waiting for dumps to be processed...");

        for (Thread curThread : threadSet) {
            curThread.join();
        }

        ErrorFileDumper.shutdown(10000L);

        stopWatch.stop();
        long totalTime = stopWatch.getTotalTimeMillis();
        double averageTime = ((double) totalTime) / ((double) LOOP_COUNT);
        logger.info("Milliseconds per exception = " + averageTime);
        logger.info(stopWatch.prettyPrint());

        Assert.assertTrue("Error dump directory does not exist !", todaysDirectory.exists());
        Assert.assertTrue("Error dump directory should have error files in it !",
                todaysDirectory.listFiles().length > 0);
    }

    @Test
    public void testOutputSystemInfoAllInParallel() throws InterruptedException {

        logger.info("Starting testOutputSystemInfoAllInParallel test...");

        StopWatch stopWatch = new StopWatch("testDumperInParallel");
        stopWatch.start(Thread.currentThread().getName() + " generating error dumps");

        ErrorFileDumper.start();

        threadSet.clear();
        final int[] dumpLengths = new int[(int) THREAD_COUNT];

        for (int i = 0; i < THREAD_COUNT; i++) {
            final int threadCounter = i;
            Thread newThread = new Thread(new Runnable() {

                public void run() {
                    // this is the call made in errors.jsp file.
                    StringWriter stringWriter = new StringWriter();
                    ErrorFileDumper.outputSystemInfo(new PrintWriter(stringWriter));
                    dumpLengths[threadCounter] = stringWriter.toString().length();
                    stringWriter = null;
                }
            }, "ErrorFileDumperTestThread" + i);
            threadSet.add(newThread);
            newThread.start();
        }

        logger.info("Waiting for dumps to be processed...");

        for (Thread curThread : threadSet) {
            curThread.join();
        }

        ErrorFileDumper.shutdown(10000L);

        stopWatch.stop();
        long totalTime = stopWatch.getTotalTimeMillis();
        double averageTime = ((double) totalTime) / ((double) LOOP_COUNT);
        logger.info("Milliseconds per exception = " + averageTime);
        logger.info(stopWatch.prettyPrint());
        for (int dumpLength : dumpLengths) {
            Assert.assertTrue("System info dump is empty", dumpLength > 0);
        }
    }

    private void generateExceptions() {
        for (int i = 0; i < LOOP_COUNT; i++) {
            MockHttpServletRequest request = new MockHttpServletRequest();
            request.setRequestURI("/cms");
            request.setQueryString("name=value");
            request.addHeader("headerName", "headerValue");
            try {
                ErrorFileDumper.dumpToFile(new Throwable("mock error " + i), (HttpServletRequest) request);
            } catch (IOException e) {
                logger.error("Error while dumping error", e);
            }
        }
    }
}