From dev-return-30347-archive-asf-public=cust-asf.ponee.io@geode.apache.org Mon Nov 26 23:11:53 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id ACF94180647 for ; Mon, 26 Nov 2018 23:11:52 +0100 (CET) Received: (qmail 90772 invoked by uid 500); 26 Nov 2018 22:11:51 -0000 Mailing-List: contact dev-help@geode.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.apache.org Delivered-To: mailing list dev@geode.apache.org Received: (qmail 90761 invoked by uid 99); 26 Nov 2018 22:11:51 -0000 Received: from mail-relay.apache.org (HELO mailrelay1-lw-us.apache.org) (207.244.88.152) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 26 Nov 2018 22:11:51 +0000 Received: from mail-vs1-f69.google.com (mail-vs1-f69.google.com [209.85.217.69]) by mailrelay1-lw-us.apache.org (ASF Mail Server at mailrelay1-lw-us.apache.org) with ESMTPSA id CD9F13BAC for ; Mon, 26 Nov 2018 22:11:50 +0000 (UTC) Received: by mail-vs1-f69.google.com with SMTP id r133so9625997vsc.3 for ; Mon, 26 Nov 2018 14:11:50 -0800 (PST) X-Gm-Message-State: AA+aEWb8MwUYupCIs15xNDy/6GUb/bN8PZ41aq/lluzw7eoveqyGY7wA DsZUKfZp7/0OKyWCsquknbIsILAtOZor48Etp14a9Dhm9KFa1EEKdUX/o8lF7z2qlLV6v2mwWm/ NmuiaWLDY01CBC1UhEyhb73GBd7teE3i9ziMutLtOFwKXPsl3kqtEnqs= X-Received: by 2002:ab0:5a31:: with SMTP id l46mr11620877uad.92.1543270309805; Mon, 26 Nov 2018 14:11:49 -0800 (PST) X-Google-Smtp-Source: AFSGD/XF12nvVMv2OJCgOPAme1JTEE5bklj99xmU3LUYXwgT/POMZMy61BrrGdFDKBPxAiKEePQygDKmqh2gKBRs/mE= X-Received: by 2002:ab0:5a31:: with SMTP id l46mr11620871uad.92.1543270309493; Mon, 26 Nov 2018 14:11:49 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Kirk Lund Date: Mon, 26 Nov 2018 14:11:38 -0800 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: Using SystemOutRule or SystemErrRule in Geode tests To: geode Content-Type: multipart/alternative; boundary="000000000000971fa0057b989e59" --000000000000971fa0057b989e59 Content-Type: text/plain; charset="UTF-8" The following unit test will pass repeatedly in both your IDE (ex: run until failure) or in stressNewTest: public class SystemOutRuleTest { @Rule public SystemOutRule systemOutRule = new SystemOutRule().enableLog(); @Test public void passesRepeatedly() { System.out.println("hello"); assertThat(systemOutRule.getLog()).contains("hello"); } } But the following test will fail after the first time the test is executed (ex: run until failure in IntelliJ) : public class SystemOutRuleTest { @Rule public SystemOutRule systemOutRule = new SystemOutRule().enableLog(); @Test public void passesFirstTime() { LogManager.getLogger().info("hello"); assertThat(systemOutRule.getLog()).contains("hello"); } } If you need to verify that a class is logging a specific message in some circumstances then you can extract that test from the Unit Test and move it to an Integration Test. You do *not* have to annotate SystemOutRule with @ClassRule but I recommend doing that especially if you're using other Rules doing some complicated setUp involving Geode classes: public class CacheLoggingIntegrationTest { private InternalCache cache; @Rule public SystemOutRule systemOutRule = new SystemOutRule().enableLog(); @Before public void setUp() { cache = (InternalCache) new CacheFactory().set(LOCATORS, "").create(); } @After public void tearDown() { cache.close(); } @Test public void passesFirstTime() { cache.getLogger().info("hello"); assertThat(systemOutRule.getLog()).contains("hello"); } } If you change the SystemOutRule in CacheLoggingIntegrationTest to a static @ClassRule: @ClassRule public static SystemOutRule systemOutRule = new SystemOutRule().enableLog(); ...then it will repeatedly pass if you run-until-failure in IntelliJ but only because IJ ends up running it as one test class. It will still fail when run repeatedly by stressNewTest or if a previous test class caused Log4J2 to startup within the same JVM. On Mon, Nov 26, 2018 at 1:46 PM Kirk Lund wrote: > Log4J and Logback both capture a reference to System.out and/or System.err > and then use that reference thereafter. This means that any manipulation of > System.out or System.err -- using System.setOut(PrintStream) or > System.setErr(PrintStream) -- probably isn't going to play nicely with > logging in general. > > Here's what that means for Geode tests... > > If you're writing a Unit Test, then that test will be executed in a > long-lived JVM in which other Unit Tests are also going to be executed. The > SystemOutRule from system-rules will work with code that uses System.out > directly but will not work repeatedly with loggers. > > If you're writing an Integration Test or Distributed Test, then that test > will be executed in a fresh JVM (fork every one is the config), so as long > as you can get the SystemOutRule before to invoke before logging, the test > will behave. In general that means you'll want to annotate it > with @BeforeClass. > > Here are a couple examples in which log4j2 captures System.out to > illustrate why SystemOutRule can't intercept the output after invoking > System.setOut(PrintStream): > > log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java:43: > private static final PrintStream DEFAULT_STREAM = System.out; > > log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java:87: > ps = System.out; > > If SystemOutRule executes its before -- System.setOut(PrintStream) -- > after the above code, logging will be printing to a different PrintStream > than the PrintStream that SystemOutRule inserted into System. > --000000000000971fa0057b989e59--