All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.internal.logging.console.taskgrouping.AbstractBasicGroupedTaskLoggingFunctionalTest.groovy Maven / Gradle / Ivy

/*
 * Copyright 2017 the original author or authors.
 *
 * Licensed 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.gradle.internal.logging.console.taskgrouping

import org.gradle.integtests.fixtures.console.AbstractConsoleGroupedTaskFunctionalTest
import org.gradle.integtests.fixtures.executer.GradleContextualExecuter
import org.gradle.integtests.fixtures.executer.GradleHandle
import org.gradle.internal.logging.sink.GroupingProgressLogEventGenerator
import org.gradle.test.fixtures.ConcurrentTestUtil
import org.gradle.test.fixtures.server.http.BlockingHttpServer
import org.junit.Rule
import spock.lang.IgnoreIf

abstract class AbstractBasicGroupedTaskLoggingFunctionalTest extends AbstractConsoleGroupedTaskFunctionalTest {
    private static long sleepTimeout = GroupingProgressLogEventGenerator.HIGH_WATERMARK_FLUSH_TIMEOUT / 2 * 3

    @Rule
    BlockingHttpServer server = new BlockingHttpServer()

    def "multi-project build tasks logs are grouped"() {
        server.start()

        given:
        settingsFile << "include '1', '2', '3'"

        buildFile << """
            subprojects {
                task log { 
                    doFirst { 
                        logger.error "Error from " + project.name
                        logger.quiet "Output from " + project.name
                        new java.net.URL("${server.uri}/log" + project.name).openConnection().getContentLength()
                        logger.quiet "Done with " + project.name 
                        logger.error "Done with " + project.name
                    } 
                }
            }
        """

        when:
        server.expectConcurrent("log1", "log2", "log3")
        result = executer.withArgument("--parallel").withTasks("log").start().waitForFinish()

        then:
        result.groupedOutput.taskCount == 3
        if (errorsShouldAppearOnStdout()) {
            // both stdout and stderr are attached to the console
            assert result.groupedOutput.task(':1:log').output == "Error from 1\nOutput from 1\nDone with 1\nDone with 1"
            assert result.groupedOutput.task(':2:log').output == "Error from 2\nOutput from 2\nDone with 2\nDone with 2"
            assert result.groupedOutput.task(':3:log').output == "Error from 3\nOutput from 3\nDone with 3\nDone with 3"
        } else {
            assert result.groupedOutput.task(':1:log').output == "Output from 1\nDone with 1"
            assert result.groupedOutput.task(':2:log').output == "Output from 2\nDone with 2"
            assert result.groupedOutput.task(':3:log').output == "Output from 3\nDone with 3"

            result.assertHasErrorOutput("Error from 1\nDone with 1")
            result.assertHasErrorOutput("Error from 2\nDone with 2")
            result.assertHasErrorOutput("Error from 3\nDone with 3")
        }
    }

    def "logs at execution time are grouped"() {
        given:
        buildFile << """
            task log {
                logger.quiet 'Logged during configuration'
                doFirst {
                    logger.quiet 'First line of text'
                    logger.quiet 'Second line of text'
                }
            }
        """

        when:
        succeeds('log')

        then:
        result.groupedOutput.task(':log').output == "First line of text\nSecond line of text"
    }

    def "system out and err gets grouped"() {
        given:
        buildFile << """
            task log {
                logger.quiet 'Logged during configuration'
                doFirst {
                    System.out.println("Standard out 1")
                    System.err.println("Standard err 1")
                    System.out.println("Standard out 2")
                    System.err.println("Standard err 2")
                }
            }
        """

        when:
        succeeds('log')

        then:
        if (errorsShouldAppearOnStdout()) {
            result.groupedOutput.task(':log').output == "Standard out 1\nStandard err 1\nStandard out 2\nStandard err 2"
        } else {
            result.groupedOutput.task(':log').output == "Standard out 1\nStandard out 2\n"
            result.assertHasErrorOutput("Standard err 1\nStandard err 2")
        }
    }

    def "grouped output is displayed for failed tasks"() {
        given:
        buildFile << """
            task log {
                logger.quiet 'Logged during configuration'
                doFirst {
                    logger.quiet 'First line of text'
                    logger.quiet ''
                    logger.quiet ''
                    logger.quiet 'Last line of text'
                    throw new GradleException('Forced failure')
                }
            }
        """
        when:
        fails('log')

        then:
        result.groupedOutput.task(':log').output =~ /First line of text\n{3,}Last line of text/
    }

    @IgnoreIf({ GradleContextualExecuter.parallel })
    def "long running task output correctly interleave with other tasks in parallel"() {
        given:
        server.start()

        buildFile << """
            project(":a") {
                task log {
                    doLast {
                        logger.quiet 'Before'
                        ${callFromBuild('a-waiting')}
                        logger.quiet 'After'
                        assert false
                    }
                }
            }

            project(":b") {
                task log {
                    doLast {
                        ${callFromBuild('b-waiting')}
                        logger.quiet 'Interrupting output'
                        ${callFromBuild('b-done')}
                    }
                }
            }

            task run {
                dependsOn project(':a').log, project(':b').log
            }
        """

        settingsFile << """
            include 'a', 'b'
        """

        when:
        def waiting = server.expectConcurrentAndBlock("a-waiting", "b-waiting")
        def done = server.expectAndBlock("b-done")
        def build = executer.withArguments("--parallel").withTasks("run").start()

        waiting.waitForAllPendingCalls()
        waiting.release("b-waiting")
        done.waitForAllPendingCalls()
        done.releaseAll()
        waiting.releaseAll()
        result = build.waitForFailure()

        then:
        result.groupedOutput.task(':a:log').output == 'Before\nAfter'
        result.groupedOutput.task(':a:log').outcome == 'FAILED'
        result.groupedOutput.task(':b:log').output == 'Interrupting output'
        result.groupedOutput.task(':b:log').outcome == null
    }

    def "long running task output are flushed after delay"() {
        server.start()

        given:
        buildFile << """
            task log {
                doLast {
                    logger.quiet 'Before'
                    ${callFromBuild('running')}
                    logger.quiet 'After'
                }
            }
        """

        def handle = server.expectAndBlock(server.get('running'))
        def gradle = executer.withTasks('log').start()

        when:
        handle.waitForAllPendingCalls()
        assertOutputContains(gradle, "Before")
        handle.releaseAll()
        result = gradle.waitForFinish()

        then:
        result.groupedOutput.task(':log').output == 'Before\nAfter'

        cleanup:
        gradle?.waitForFinish()
    }

    String callFromBuild(String name) {
        return "new URL('${server.uri}/${name}').text"
    }

    protected static void assertOutputContains(GradleHandle gradle, String str) {
        ConcurrentTestUtil.poll(sleepTimeout/1000 as double) {
            assert gradle.standardOutput =~ /(?ms)$str/
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy