1 package kotlinx.coroutines.slf4j 2 3 import kotlinx.coroutines.testing.* 4 import kotlinx.coroutines.* 5 import org.junit.* 6 import org.junit.Test 7 import org.slf4j.* 8 import kotlin.coroutines.* 9 import kotlin.test.* 10 11 class MDCContextTest : TestBase() { 12 @Before setUpnull13 fun setUp() { 14 MDC.clear() 15 } 16 17 @After tearDownnull18 fun tearDown() { 19 MDC.clear() 20 } 21 22 @Test <lambda>null23 fun testContextIsNotPassedByDefaultBetweenCoroutines() = runTest { 24 expect(1) 25 MDC.put("myKey", "myValue") 26 // Standalone launch 27 GlobalScope.launch { 28 assertNull(MDC.get("myKey")) 29 expect(2) 30 }.join() 31 finish(3) 32 } 33 34 @Test <lambda>null35 fun testContextCanBePassedBetweenCoroutines() = runTest { 36 expect(1) 37 MDC.put("myKey", "myValue") 38 // Scoped launch with MDCContext element 39 launch(MDCContext()) { 40 assertEquals("myValue", MDC.get("myKey")) 41 expect(2) 42 }.join() 43 44 finish(3) 45 } 46 47 @Test <lambda>null48 fun testContextInheritance() = runTest { 49 expect(1) 50 MDC.put("myKey", "myValue") 51 withContext(MDCContext()) { 52 MDC.put("myKey", "myValue2") 53 // Scoped launch with inherited MDContext element 54 launch(Dispatchers.Default) { 55 assertEquals("myValue", MDC.get("myKey")) 56 expect(2) 57 }.join() 58 59 finish(3) 60 } 61 assertEquals("myValue", MDC.get("myKey")) 62 } 63 64 @Test testContextPassedWhileOnMainThreadnull65 fun testContextPassedWhileOnMainThread() { 66 MDC.put("myKey", "myValue") 67 // No MDCContext element 68 runBlocking { 69 assertEquals("myValue", MDC.get("myKey")) 70 } 71 } 72 73 @Test testContextCanBePassedWhileOnMainThreadnull74 fun testContextCanBePassedWhileOnMainThread() { 75 MDC.put("myKey", "myValue") 76 runBlocking(MDCContext()) { 77 assertEquals("myValue", MDC.get("myKey")) 78 } 79 } 80 81 @Test testContextNeededWithOtherContextnull82 fun testContextNeededWithOtherContext() { 83 MDC.put("myKey", "myValue") 84 runBlocking(MDCContext()) { 85 assertEquals("myValue", MDC.get("myKey")) 86 } 87 } 88 89 @Test testContextMayBeEmptynull90 fun testContextMayBeEmpty() { 91 runBlocking(MDCContext()) { 92 assertNull(MDC.get("myKey")) 93 } 94 } 95 96 @Test <lambda>null97 fun testContextWithContext() = runTest { 98 MDC.put("myKey", "myValue") 99 val mainDispatcher = kotlin.coroutines.coroutineContext[ContinuationInterceptor]!! 100 withContext(Dispatchers.Default + MDCContext()) { 101 assertEquals("myValue", MDC.get("myKey")) 102 assertEquals("myValue", coroutineContext[MDCContext]?.contextMap?.get("myKey")) 103 withContext(mainDispatcher) { 104 assertEquals("myValue", MDC.get("myKey")) 105 } 106 } 107 } 108 109 /** Tests that the initially captured MDC context gets restored after suspension. */ 110 @Test <lambda>null111 fun testSuspensionsUndoingMdcContextUpdates() = runTest { 112 MDC.put("a", "b") 113 withContext(MDCContext()) { 114 MDC.put("key", "value") 115 assertEquals("b", MDC.get("a")) 116 yield() 117 assertNull(MDC.get("key")) 118 assertEquals("b", MDC.get("a")) 119 } 120 } 121 122 /** Tests capturing and restoring the MDC context. */ 123 @Test <lambda>null124 fun testRestoringMdcContext() = runTest { 125 MDC.put("a", "b") 126 val contextMap = withContext(MDCContext()) { 127 MDC.put("key", "value") 128 assertEquals("b", MDC.get("a")) 129 withContext(MDCContext()) { 130 assertEquals("value", MDC.get("key")) 131 MDC.put("key2", "value2") 132 assertEquals("value2", MDC.get("key2")) 133 withContext(MDCContext()) { 134 yield() 135 MDC.getCopyOfContextMap() 136 } 137 } 138 } 139 MDC.setContextMap(contextMap) 140 assertEquals("value2", MDC.get("key2")) 141 assertEquals("value", MDC.get("key")) 142 assertEquals("b", MDC.get("a")) 143 } 144 } 145