001/** 002 * Copyright (c) 2004-2013 QOS.ch, Copyright (C) 2015 Google Inc. 003 * All rights reserved. 004 * 005 * Permission is hereby granted, free of charge, to any person obtaining 006 * a copy of this software and associated documentation files (the 007 * "Software"), to deal in the Software without restriction, including 008 * without limitation the rights to use, copy, modify, merge, publish, 009 * distribute, sublicense, and/or sell copies of the Software, and to 010 * permit persons to whom the Software is furnished to do so, subject to 011 * the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be 014 * included in all copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 023 */ 024 025package org.slf4j.helpers; 026 027import static org.junit.Assert.assertEquals; 028import static org.junit.Assert.assertFalse; 029import static org.junit.Assert.assertNull; 030import static org.junit.Assert.fail; 031 032import java.lang.Thread.UncaughtExceptionHandler; 033import java.util.Map; 034 035import org.junit.After; 036import org.junit.Test; 037import org.slf4j.spi.MDCAdapter; 038 039/** 040 * Tests for {@link BasicMDCAdapter} 041 * 042 * @author Lukasz Cwik 043 */ 044public class BasicMDCAdapterTest { 045 MDCAdapter mdc = new BasicMDCAdapter(); 046 047 @After 048 public void tearDown() throws Exception { 049 mdc.clear(); 050 } 051 052 @Test 053 public void testSettingAndGettingWithMDC() { 054 assertNull(mdc.get("testKey")); 055 mdc.put("testKey", "testValue"); 056 assertEquals(mdc.get("testKey"), "testValue"); 057 } 058 059 @Test 060 public void testOverwritingAKeyInMDC() { 061 assertNull(mdc.get("testKey")); 062 mdc.put("testKey", "testValue"); 063 mdc.put("testKey", "differentTestValue"); 064 assertEquals(mdc.get("testKey"), "differentTestValue"); 065 } 066 067 @Test 068 public void testClearingMDC() { 069 mdc.put("testKey", "testValue"); 070 assertFalse(mdc.getCopyOfContextMap().isEmpty()); 071 mdc.clear(); 072 assertNull(mdc.getCopyOfContextMap()); 073 } 074 075 @Test 076 public void testGetCopyOfContextMapFromMDC() { 077 mdc.put("testKey", "testValue"); 078 Map<String, String> copy = mdc.getCopyOfContextMap(); 079 mdc.put("anotherTestKey", "anotherTestValue"); 080 assertFalse(copy.size() == mdc.getCopyOfContextMap().size()); 081 } 082 083 @Test 084 public void testMDCInheritsValuesFromParentThread() throws Exception { 085 mdc.put("parentKey", "parentValue"); 086 runAndWait(new Runnable() { 087 public void run() { 088 mdc.put("childKey", "childValue"); 089 assertEquals("parentValue", mdc.get("parentKey")); 090 } 091 }); 092 } 093 094 @Test 095 public void testMDCDoesntGetValuesFromChildThread() throws Exception { 096 mdc.put("parentKey", "parentValue"); 097 runAndWait(new Runnable() { 098 public void run() { 099 mdc.put("childKey", "childValue"); 100 } 101 }); 102 assertEquals("parentValue", mdc.get("parentKey")); 103 assertNull(mdc.get("childKey")); 104 } 105 106 @Test 107 public void testMDCChildThreadCanOverwriteParentThread() throws Exception { 108 mdc.put("sharedKey", "parentValue"); 109 runAndWait(new Runnable() { 110 public void run() { 111 assertEquals("parentValue", mdc.get("sharedKey")); 112 mdc.put("sharedKey", "childValue"); 113 assertEquals("childValue", mdc.get("sharedKey")); 114 } 115 }); 116 assertEquals("parentValue", mdc.get("sharedKey")); 117 } 118 119 private void runAndWait(Runnable runnable) throws Exception { 120 RecordingExceptionHandler handler = new RecordingExceptionHandler(); 121 Thread thread = new Thread(runnable); 122 thread.setUncaughtExceptionHandler(handler); 123 thread.start(); 124 try { 125 thread.join(); 126 } catch (Throwable t) { 127 fail("Unexpected failure in child thread:" + t.getMessage()); 128 } 129 assertFalse(handler.getMessage(), handler.hadException()); 130 } 131 132 /** A {@link UncaughtExceptionHandler} that records whether the thread threw an exception. */ 133 private static class RecordingExceptionHandler implements UncaughtExceptionHandler { 134 private Throwable exception; 135 136 public void uncaughtException(Thread t, Throwable e) { 137 exception = e; 138 } 139 140 boolean hadException() { 141 return exception != null; 142 } 143 144 String getMessage() { 145 return exception != null ? exception.getMessage() : ""; 146 } 147 } 148}