<commit_before>package org.http4s
package testing

import org.specs2.concurrent.ExecutionEnv
import org.specs2.control.Debug._
import org.specs2.execute._
import org.specs2.matcher.TerminationMatchers._
import org.specs2.matcher._
import org.specs2.specification.{Around, Context, EachContext}
import org.specs2.specification.core._

import scala.collection.JavaConverters._
import scala.concurrent.duration._

/**
 * This trait can be used to add a global time out to each example or for a specific one:
 *
 *  - for each example mix-in the trait
 *  - for a single example import the object and use the upTo context:
 *
 *   my example must terminate in a reasonable amount of time \${upTo(3.seconds)(e1)}
 */
trait ThreadDumpOnTimeout extends EachContext {

  /**
   * Return number blocking waiting periods to partition the timeout into.
   *
   * `ThreadDumpOnTimeout` uses {{TerminationMatchers.terminate()}}, which calls
   * `Thread.sleep()` for a period of time and checks if the spec is still running
   * when `sleep()` returns. If we have a long timeout, say 30 seconds, and do not
   * slice it up, the spec will take 30 seconds to complete even if the real work
   * finished after 100 milliseconds.
   */
  def slices: Int = 10

  /**
   * Overall time to wait before triggering a thread dump.
   *
   * Spec will take ''at least'' `timeout / slices` to complete when `ThreadDumpOnTimeout` is mixed in.
   */
  def triggerThreadDumpAfter: Duration = 5.seconds

  def context: Env => Context = { env: Env =>
    aroundTimeout(triggerThreadDumpAfter)(env.executionEnv)
  }

  // borrows heavily from `ExamplesTimeout` in specs2
  def aroundTimeout(to: Duration)(implicit ee: ExecutionEnv): Around =
    new Around {
      def around[T : AsResult](t: =>T): Result = {
        lazy val result = t
        val exp: Expectable[T] = createExpectable(result)
        val outcome = terminate(retries = slices, sleep = (to.toMillis / slices).millis)(ee)(exp)
        threadDumpOnFailure(outcome)<commit_msg>avoid implicit numeric widening<commit_after>package org.http4s
package testing

import org.specs2.concurrent.ExecutionEnv
import org.specs2.control.Debug._
import org.specs2.execute._
import org.specs2.matcher.TerminationMatchers._
import org.specs2.matcher._
import org.specs2.specification.{Around, Context, EachContext}
import org.specs2.specification.core._

import scala.collection.JavaConverters._
import scala.concurrent.duration._

/**
 * This trait can be used to add a global time out to each example or for a specific one:
 *
 *  - for each example mix-in the trait
 *  - for a single example import the object and use the upTo context:
 *
 *   my example must terminate in a reasonable amount of time \${upTo(3.seconds)(e1)}
 */
trait ThreadDumpOnTimeout extends EachContext {

  /**
   * Return number blocking waiting periods to partition the timeout into.
   *
   * `ThreadDumpOnTimeout` uses {{TerminationMatchers.terminate()}}, which calls
   * `Thread.sleep()` for a period of time and checks if the spec is still running
   * when `sleep()` returns. If we have a long timeout, say 30 seconds, and do not
   * slice it up, the spec will take 30 seconds to complete even if the real work
   * finished after 100 milliseconds.
   */
  def slices: Int = 10

  /**
   * Overall time to wait before triggering a thread dump.
   *
   * Spec will take ''at least'' `timeout / slices` to complete when `ThreadDumpOnTimeout` is mixed in.
   */
  def triggerThreadDumpAfter: Duration = 5.seconds

  def context: Env => Context = { env: Env =>
    aroundTimeout(triggerThreadDumpAfter)(env.executionEnv)
  }

  // borrows heavily from `ExamplesTimeout` in specs2
  def aroundTimeout(to: Duration)(implicit ee: ExecutionEnv): Around =
    new Around {
      def around[T : AsResult](t: =>T): Result = {
        lazy val result = t
        val exp: Expectable[T] = createExpectable(result)
        val msPerSlice = to.toMillis / slices
        val outcome = terminate(retries = slices, sleep = msPerSlice.millis)(ee)(exp)
        threadDumpOnFailure(outcome)
{'fraction_non_alphanumeric': 0.09151128557409224, 'fraction_numerical': 0.010304219823356232, 'mean_word_length': 3.654109589041096, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3316372', 'n_tokens_mistral': 1228, 'n_tokens_neox': 1169, 'n_words': 431}