<commit_before>/*
 * 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.atomic.AtomicInteger;
import java.util.logging.Filter;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;

import javax.servlet.http.HttpServletResponse;


import org.junit.Assert;
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.util.buf.ByteChunk;

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.addServletMapping("/leak1", "leakServlet1");


        tomcat.start();

        // Configure logging filter to check leak message appears
        LogValidationFilter f = new LogValidationFilter(
                "The web application [ROOT] created a ThreadLocal with key of");
        LogManager.getLogManager().getLogger(
                "org.apache.catalina.loader.WebappClassLoaderBase").setFilter(f);

        // Need to force loading of all web application classes via the web
        // application class loader
        loadClass("TesterCounter",
                (WebappClassLoader) ctx.getLoader().getClassLoader());
        loadClass("TesterLeakingServlet1",
                (WebappClassLoader) 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.addServletMapping("/leak2", "leakServlet2");

        tomcat.start();

        // Configure logging filter to check leak message appears
        LogValidationFilter f = new LogValidationFilter(
                "The web application [ROOT] created a ThreadLocal with key of");
        LogManager.getLogManager().getLogger(
                "org.apache.catalina.loader.WebappClassLoaderBase").setFilter(f);

        // Need to force loading of all web application classes via the web<commit_msg>Prevent threads from being renewed if a leak is detected. This might be why the memoty leak tests sometimes fails on Gump.<commit_after>/*
 * 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 java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Filter;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;

import javax.servlet.http.HttpServletResponse;

import org.junit.Assert;
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.util.buf.ByteChunk;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;

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.addServletMapping("/leak1", "leakServlet1");

        tomcat.start();

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

        // Configure logging filter to check leak message appears
        LogValidationFilter f = new LogValidationFilter(
                "The web application [ROOT] created a ThreadLocal with key of");
        LogManager.getLogManager().getLogger(
                "org.apache.catalina.loader.WebappClassLoaderBase").setFilter(f);

        // Need to force loading of all web application classes via the web
        // application class loader
        loadClass("TesterCounter",
                (WebappClassLoader) ctx.getLoader().getClassLoader());
        loadClass("TesterLeakingServlet1",
                (WebappClassLoader) 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.addServletMapping("/leak2", "leakServlet2");

        tomcat.start();

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

        // Configure logging filter to check leak message appears
        LogValidationFilter f = new LogValidationFilter(
                "The web application [ROOT] created a ThreadLocal with key of");
        LogManager.getLogManager().getLogger(
                "org.apache.catalina.loader.WebappClassLoaderBase").setFilter(f);

        // Need to force loading of all web application classes via the web
{'fraction_non_alphanumeric': 0.089571201694018, 'fraction_numerical': 0.004023292747485442, 'mean_word_length': 2.98902027027027, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6819487', 'n_tokens_mistral': 2479, 'n_tokens_neox': 2381, 'n_words': 750}