/*
 * 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.catalina.loader;

import java.io.InputStream;
import java.util.concurrent.Executor;

import javax.servlet.http.HttpServletResponse;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import org.apache.catalina.Context;
import org.apache.catalina.core.JreMemoryLeakPreventionListener;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.unittest.TesterLogValidationFilter;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;

/*
 * These unit tests are ignored by default as they are not reliable. They have
 * been failing regularly on Gump for some time and have recently started to
 * fail regularly on markt's laptop.
 *
 * The problem is that the ThreadLocal Maps are affected by GC. If GC occurs at
 * the wrong point, the leaking ThreadLocal will be cleaned up and the test will
 * fail. It is not possible to force the test to pass without effectively
 * changing the nature of the test so it no longer tests detection of leaks via
 * ThreadLocals.
 *
 * The test has been left in place since it will work reasonably reliably on
 * most systems (just not all and particularly some of the ASF's CI systems) and
 * still may be useful if a bug is reported in this area in the future.
 */
@Ignore
public class TestWebappClassLoaderThreadLocalMemoryLeak extends TomcatBaseTest {

    @Test
    public void testThreadLocalLeak1() throws Exception {

        Tomcat tomcat = getTomcatInstance();
        // Need to make sure we see a leak for the right reasons
        tomcat.getServer().addLifecycleListener(
                new JreMemoryLeakPreventionListener());

        // No file system docBase required
        Context ctx = tomcat.addContext("", null);

        Tomcat.addServlet(ctx, "leakServlet1",
                "org.apache.tomcat.unittest.TesterLeakingServlet1");
        ctx.addServletMappingDecoded("/leak1", "leakServlet1");

        tomcat.start();

        Executor executor = tomcat.getConnector().getProtocolHandler().getExecutor();
        ((ThreadPoolExecutor) executor).setThreadRenewalDelay(-1);

        // Configure logging filter to check leak message appears
        TesterLogValidationFilter f = TesterLogValidationFilter.add(null,
                "The web application [ROOT] created a ThreadLocal with key of", null,
                "org.apache.catalina.loader.WebappClassLoaderBase");

        // Need to force loading of all web application classes via the web
        // application class loader
        loadClass("TesterCounter",
                (WebappClassLoaderBase) ctx.getLoader().getClassLoader());
        loadClass("TesterLeakingServlet1",
                (WebappClassLoaderBase) ctx.getLoader().getClassLoader());

        // This will trigger the ThreadLocal creation
        int rc = getUrl("http://localhost:" + getPort() + "/leak1",
                new ByteChunk(), null);

        // Make sure request is OK
        Assert.assertEquals(HttpServletResponse.SC_OK, rc);

        // Destroy the context
        ctx.stop();
        tomcat.getHost().removeChild(ctx);
        ctx = null;

        // Make sure we have a memory leak
        String[] leaks = ((StandardHost) tomcat.getHost())
                .findReloadedContextMemoryLeaks();
        Assert.assertNotNull(leaks);
        Assert.assertTrue(leaks.length > 0);

        // Make sure the message was logged
        Assert.assertEquals(1, f.getMessageCount());
    }


    @Test
    public void testThreadLocalLeak2() throws Exception {

        Tomcat tomcat = getTomcatInstance();
        // Need to make sure we see a leak for the right reasons
        tomcat.getServer().addLifecycleListener(
                new JreMemoryLeakPreventionListener());

        // No file system docBase required
        Context ctx = tomcat.addContext("", null);

        Tomcat.addServlet(ctx, "leakServlet2",
                "org.apache.tomcat.unittest.TesterLeakingServlet2");
        ctx.addServletMappingDecoded("/leak2", "leakServlet2");

        tomcat.start();

        Executor executor = tomcat.getConnector().getProtocolHandler().getExecutor();
        ((ThreadPoolExecutor) executor).setThreadRenewalDelay(-1);

        // Configure logging filter to check leak message appears
        TesterLogValidationFilter f = TesterLogValidationFilter.add(null,
                "The web application [ROOT] created a ThreadLocal with key of", null,
                "org.apache.catalina.loader.WebappClassLoaderBase");

        // Need to force loading of all web application classes via the web
        // application class loader
        loadClass("TesterCounter",
                (WebappClassLoaderBase) ctx.getLoader().getClassLoader());
        loadClass("TesterThreadScopedHolder",
                (WebappClassLoaderBase) ctx.getLoader().getClassLoader());
        loadClass("TesterLeakingServlet2",
                (WebappClassLoaderBase) ctx.getLoader().getClassLoader());

        // This will trigger the ThreadLocal creation
        int rc = getUrl("http://localhost:" + getPort() + "/leak2",
                new ByteChunk(), null);

        // Make sure request is OK
        Assert.assertEquals(HttpServletResponse.SC_OK, rc);

        // Destroy the context
        ctx.stop();
        tomcat.getHost().removeChild(ctx);
        ctx = null;

        // Make sure we have a memory leak
        String[] leaks = ((StandardHost) tomcat.getHost())
                .findReloadedContextMemoryLeaks();
        Assert.assertNotNull(leaks);
        Assert.assertTrue(leaks.length > 0);

        // Make sure the message was logged
        Assert.assertEquals(1, f.getMessageCount());
    }


    /**
     * Utility method to ensure that classes are loaded by the
     * WebappClassLoader. We can't just create classes since they will be loaded
     * by the current class loader rather than the WebappClassLoader. This would
     * mean that no leak occurred making the test for a leak rather pointless
     * So, we load the bytes via the current class loader but define the class
     * with the WebappClassLoader.
     *
     * This method assumes that all classes are in the current package.
     */
    private void loadClass(String name, WebappClassLoaderBase cl) throws Exception {
        try (InputStream is = cl.getResourceAsStream(
                "org/apache/tomcat/unittest/" + name + ".class")) {
            // We know roughly how big the class will be (~ 1K) so allow 2k as a
            // starting point
            byte[] classBytes = new byte[2048];
            int offset = 0;
            int read = is.read(classBytes, offset, classBytes.length-offset);
            while (read > -1) {
                offset += read;
                if (offset == classBytes.length) {
                    // Buffer full - double size
                    byte[] tmp = new byte[classBytes.length * 2];
                    System.arraycopy(classBytes, 0, tmp, 0, classBytes.length);
                    classBytes = tmp;
                }
                read = is.read(classBytes, offset, classBytes.length-offset);
            }
            Class<?> lpClass = cl.doDefineClass(
                    "org.apache.tomcat.unittest." + name, classBytes, 0,
                    offset, cl.getClass().getProtectionDomain());
            // Make sure we can create an instance
            Object obj = lpClass.getConstructor().newInstance();
            obj.toString();
        }
    }
}