/*
 * 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.logging.log4j.util;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Tests that the Unbox ring buffer size is configurable.
 * Must be run in a separate process as the other UnboxTest or the last-run test will fail.
 */
public class UnboxConfigurableTest {
    @BeforeClass
    public static void beforeClass() {
        System.setProperty("log4j.unbox.ringbuffer.size", "65");
    }

    @AfterClass
    public static void afterClass() {
        System.clearProperty("log4j.unbox.ringbuffer.size");
    }

    @Test
    public void testBoxConfiguredTo128Slots() throws Exception {
        // next power of 2 that is 65 or more
        assertEquals(128, Unbox.getRingbufferSize());
    }

    @Test
    public void testBoxSuccessfullyConfiguredTo128Slots() throws Exception {
        final int MAX = 128;
        final StringBuilder[] probe = new StringBuilder[MAX * 3];
        for (int i = 0; i <= probe.length - 8; ) {
            probe[i++] = Unbox.box(true);
            probe[i++] = Unbox.box('c');
            probe[i++] = Unbox.box(Byte.MAX_VALUE);
            probe[i++] = Unbox.box(Double.MAX_VALUE);
            probe[i++] = Unbox.box(Float.MAX_VALUE);
            probe[i++] = Unbox.box(Integer.MAX_VALUE);
            probe[i++] = Unbox.box(Long.MAX_VALUE);
            probe[i++] = Unbox.box(Short.MAX_VALUE);
        }
        for (int i = 0; i < probe.length - MAX; i++) {
            assertSame("probe[" + i +"], probe[" + (i + MAX) +"]", probe[i], probe[i + MAX]);
            for (int j = 1; j < MAX - 1; j++) {
                assertNotSame("probe[" + i +"], probe[" + (i + j) +"]", probe[i], probe[i + j]);
            }
        }
    }
}
@@ -834,16 +834,84 @@
 .util;%0A%0A
+import java.lang.reflect.Field;%0Aimport java.lang.reflect.Modifier;%0A%0A
 import o
@@ -927,24 +927,24 @@
 AfterClass;%0A
-
 import org.j
@@ -1390,24 +1390,41 @@
 afterClass()
+ throws Exception
  %7B%0A        S
@@ -1474,16 +1474,481 @@
 .size%22);
+%0A%0A        // ensure subsequent tests (which assume 32 slots) pass%0A        final Field field = Unbox.class.getDeclaredField(%22RINGBUFFER_SIZE%22);%0A        field.setAccessible(true); // make non-private%0A%0A        final Field modifierField = Field.class.getDeclaredField(%22modifiers%22);%0A        modifierField.setAccessible(true);%0A        modifierField.setInt(field, field.getModifiers() &~ Modifier.FINAL); // make non-final%0A%0A        field.set(null, 32); // reset to default
 %0A    %7D%0A%0A

reset Unbox buffer to default size after configurable test