Принудительно выполнить задачу внутри теста, когда тайм-аут теста спока - PullRequest
1 голос
/ 09 марта 2020

Под названием

Например, у меня есть следующие тестовые случаи.

class StartupTest {


    def deploymentPath = "build/milestone/deployment"

    void checkConnectedProducts(){
        def productConnected = XXXhelper.countConnectedProducts()
        //Called another function in another class to check the number of connected products, every 1 sec
        while (productConnected>2){
            Thread.sleep(1000)
            productConnected = XXXhelper.countConnectedProducts()
        }
    }

    int countError(){
        def error = xxx.logFinder.search("(ERROR)",TimeFrames.from(LocalDateTime.now().minusSeconds(20)).to(LocalDateTime.now().plusSeconds(20)))
        return error.size()
    }

    @Timeout(80)
    def 'Start_test'() {

    setup:
    //do some setup here

    when: 'Test_started'
    //do something here

    and: 'Check_something'
    //check something here

    then: 'Validate_something'
    checkConnectedProducts()

    cleanup:
    //Call the function in another class to zip the file and send out message to slack
    File log = new File("$deploymentPath/logs")
    def error = countError()
    def zipFile = "xxx.zip"
    IOHelper.createZip(log,zipFile)
    File zipFile = new File(zipFile)

    //Pass the zip to another class
    ZipUploader.Slack(zipFile,error)   

   }
}

Ниже класс используется для загрузки сжатого файла и отправки сообщения в свободный канал

class ZipUploader {

    static uploadLocation = System.getProperty("benchmark-result-server")
    static proxyHost = System.getProperty("proxy-host")
    static proxyPort = System.getProperty("proxy-port")

    static Slack(File file, int errorCount){

        //Upload file
        OkHttpClient client = new OkHttpClient()
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("zip", file.name,
                        RequestBody.create(file, MediaType.parse(com.google.common.net.MediaType.ZIP.type()))
                )
                .build()

        Request request = new Request.Builder()
                .url("$uploadLocation/!/xxxxxxxxxxxx")
                .post(requestBody)
                .build()

        //Check the response
        Response response = client.newCall(request).execute()
        if (!response.isSuccessful()) throw new Exception("File cannot be uploaded" + response)

        //Slack
        OkHttpClient clientSlack = new OkHttpClient().newBuilder()
                .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
                .build()
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "{\n    \"text\": \"Test has been finished \\t Error Log: $errorCount"\n}")
        Request requestSlack = new Request.Builder()
                .url("https://hooks.slack.com/services/xxxxxxx/xxxxxx/xxxxxx?Content-type=application/json")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build()
        Response responseSlack = clientSlack.newCall(requestSlack).execute()

        //Check the response
        if (!responseSlack.isSuccessful()) throw new Exception("Failed to send message to slack " + responseSlack)

    }
}

Так что, если тест выполняется в течение 80 с c, функция очистки может быть выполнена успешно, но я также хочу, чтобы функция выполнялась даже при превышении таймаута теста, я не знаю, как этого добиться.

Он просто остановит весь тест посередине, если тест превысит исключение тайм-аут и возврат тайм-аута, и функция под очисткой: не будет выполнена, включая функцию загрузки zip и отправки уведомления о слабом ходе.

Ответы [ 2 ]

0 голосов
/ 10 марта 2020

@ kriegaex, спасибо за ваш ответ. Для моего журнала ошибок он возвращается, как показано ниже.

[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0.50 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1.00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2.00 seconds.

Method timed out after 70.00 seconds
Method timed out after 70.00 seconds
    at app//xxx.checkConnectedProducts(StartupTest.groovy:36)
    at xxx.StartupTest.Start_test(StartupTest.groovy:71)

xxx.StartupTest > Start_test STANDARD_OUT
    [spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0.50 seconds.
    [spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1.00 seconds.
    [spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2.00 seconds.
Gradle Test Executor 4 finished executing tests.
> Task :test
TRACE [startup log cleaner] StartupLogFactory - Flushing delayed logs as application terminates...
TRACE [startup log cleaner] StartupLogFactory - Caution: timestamps are those at the time of the flush!
DEBUG [startup log cleaner] Connector - Connecting to localhost:6450 with user admin
TRACE [startup log cleaner] StartupLogFactory - Finished flushing delayed logs.
xxx.StartupTest > Start_test FAILED
    Method timed out after 70.00 seconds
        at app//xxx.StartupTest.checkConnectedProducts(StartupTest.groovy:36)
        at xxx.StartupTest.Start_test(StartupTest.groovy:71)
DEBUG [pool-10-thread-2] Connector - Connecting to 0.0.0.0:6450 with user <null>
1 test completed, 1 failed

Это просто остановилось на checkConnectedProducts (). И не продолжайте IOHelper.createZip(log,zipFile) в разделе очистки: блок.

Я попытался добавить println ("ab c") в cleanup: block, он действительно может быть выполнен после тайм-аута, но не функция zip и функция загрузки zip-класса.

Не могли бы вы посоветовать, как сделать IOHelper.createZip, а также Zipuploader при очистке: блок для запуска после тайм-аута? В моем случае они не продолжались. Большое спасибо!!!

0 голосов
/ 10 марта 2020

Извините, что опубликовал это как ответ, а не комментарий, но мне нужно место для кода.

Я не могу воспроизвести вашу проблему, учитывая предоставленные вами фрагменты кода вместо MCVE . Я воспроизвел упрощенную версию вашей ситуации, например, просто заменив в вашем примере операции, отнимающие много времени, на операторы Groovy sleep или Java Thread.sleep:

package de.scrum_master.stackoverflow.q60601740

import spock.lang.Specification
import spock.lang.Timeout

import static java.lang.System.currentTimeMillis

class StartupTest extends Specification {
  def startTime = currentTimeMillis()

  def timeElapsed() {
    currentTimeMillis() - startTime
  }

  void checkConnectedProducts() {
    for (int i = 1; i <= 5; i++) {
      println "${timeElapsed()} | checkConnectedProducts #$i, sleeping 1 s"
      Thread.sleep(1000)
    }
  }

  int countError() {
    println "${timeElapsed()} | countError, sleeping 4 s"
    sleep 4000
    return 3
  }

  @Timeout(3)
  def 'Start_test'() {
    setup:
    true

    when: 'Test_started'
    true

    and: 'Check_something'
    true

    then: 'Validate_something'
    checkConnectedProducts()

    cleanup:
    countError()
    println "${timeElapsed()} | cleanup, sleeping 4 s"
    sleep 4000
    println "${timeElapsed()} | cleanup finished"
  }
}

Журнал консоли выглядит как ожидается:

64 | checkConnectedProducts #1, sleeping 1 s
1112 | checkConnectedProducts #2, sleeping 1 s
2114 | checkConnectedProducts #3, sleeping 1 s
3011 | countError, sleeping 4 s
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0,50 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1,00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2,00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 4,00 seconds.
7012 | cleanup, sleeping 4 s
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 8,00 seconds.
11012 | cleanup finished

Method timed out after 3,00 seconds

    at de.scrum_master.stackoverflow.q60601740.StartupTest.checkConnectedProducts(StartupTest.groovy:18)
    at de.scrum_master.stackoverflow.q60601740.StartupTest.Start_test(StartupTest.groovy:40)

Как вы можете видеть, первые 3 итерации for l oop, каждая из которых занимает ~ 1 с, выполняются до того, как тайм-аут 3 с прерывает тест в методе вызывается из блока then:. После этого блок очистки выполняется полностью, как вызываемый метод, так и прямой sleep, каждый из которых тратит ~ 4 с в дополнение к 3 истекшим секундам. В общем, у нас есть 3 + 4 + 4 = 11 секунд, так что все работает как положено.

Если вы не можете предоставить MCVE, воспроизводящий вашу проблему, как вас об этом попросил Тим, я думаю, что в этом нет никаких проблем. Говорите, скорее, о чем-то, что вы неверно истолковали из выходных данных журнала или о другой проблеме в вашем коде, которую вы не показывали нам, такой как операция очистки или zip, выполненная в дополнительном потоке.

...