<commit_before>package mesosphere.mesos

import mesosphere.marathon.Protos.{ Constraint, MarathonTask }
import com.google.common.collect.Lists
import mesosphere.marathon.Protos.Constraint.Operator
import mesosphere.marathon.state.AppDefinition
import org.scalatest.{ Matchers, GivenWhenThen }
import scala.collection.JavaConverters._
import scala.util.Random
import mesosphere.mesos.protos.{ FrameworkID, SlaveID, OfferID, TextAttribute }
import org.apache.mesos.Protos.{ Offer, Attribute }
import mesosphere.marathon.MarathonSpec

class ConstraintsTest extends MarathonSpec with GivenWhenThen with Matchers {

  import mesosphere.mesos.protos.Implicits._

  test("Select tasks to kill for a single group by works") {
    Given("app with hostname group_by and 20 tasks even distributed on 2 hosts")
    val app = AppDefinition(constraints = Set(makeConstraint("hostname", Operator.GROUP_BY, "")))
    val tasks = 0.to(19).map(num => makeTaskWithHost(s"$num", s"srv${num % 2}")).toSet

    When("10 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks, 10)

    Then("10 tasks got selected and evenly distributed")
    result should have size 10
    val dist = result.groupBy(_.getId.toInt % 2 == 1)
    dist should have size 2
    dist.values.head should have size 5
  }

  test("Select only tasks to kill for an unbalanced distribution") {
    Given("app with hostname group_by and 30 tasks uneven distributed on 2 hosts")
    val app = AppDefinition(constraints = Set(makeConstraint("hostname", Operator.GROUP_BY, "")))
    val tasks = 0.to(19).map(num => makeTaskWithHost(s"$num", s"srv1")) ++
      20.to(29).map(num => makeTaskWithHost(s"$num", s"srv2"))

    When("10 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks.toSet, 10)

    Then("All 10 tasks are from srv1")
    result should have size 10
    result.forall(_.getHost == "srv1") should be(true)
  }

  test("Select tasks to kill for multiple group by works") {
    Given("app with 2 group_by distributions and 40 tasks even distributed")
    val app = AppDefinition(constraints = Set(
      makeConstraint("rack", Operator.GROUP_BY, ""),
      makeConstraint("color", Operator.GROUP_BY, "")))
    val tasks =
      0.to(9).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-1", "color" -> "blue"))) ++
        10.to(19).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-1", "color" -> "green"))) ++
        20.to(29).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-2", "color" -> "blue"))) ++
        30.to(39).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-2", "color" -> "green")))

    When("20 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks.toSet, 20)

    Then("20 tasks got selected and evenly distributed")
    result should have size 20
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "rack-1")) should be(10)
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "rack-1")) should be(10)
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "blue")) should be(10)
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "green")) should be(10)
  }

  test("Does not select any task without constraint") {
    Given("app with hostname group_by and 10 tasks even distributed on 5 hosts")
    val app = AppDefinition()
    val tasks = 0.to(9).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-1", "color" -> "blue")))

    When("10 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks.toSet, 5)

    Then("0 tasks got selected")
    result should have size 0
  }

  test("UniqueHostConstraint") {
    val task1_host1 = makeTaskWithHost("task1", "host1")
    val task2_host2 = makeTaskWithHost("task2", "host2")
    val task3_host3 = makeTaskWithHost("task3", "host3")
    val attributes: Set[Attribute] = Set()

    val firstTask = Set()<commit_msg>Fixed duplicate assertion in ConstraintsTest.<commit_after>package mesosphere.mesos

import mesosphere.marathon.Protos.{ Constraint, MarathonTask }
import com.google.common.collect.Lists
import mesosphere.marathon.Protos.Constraint.Operator
import mesosphere.marathon.state.AppDefinition
import org.scalatest.{ Matchers, GivenWhenThen }
import scala.collection.JavaConverters._
import scala.util.Random
import mesosphere.mesos.protos.{ FrameworkID, SlaveID, OfferID, TextAttribute }
import org.apache.mesos.Protos.{ Offer, Attribute }
import mesosphere.marathon.MarathonSpec

class ConstraintsTest extends MarathonSpec with GivenWhenThen with Matchers {

  import mesosphere.mesos.protos.Implicits._

  test("Select tasks to kill for a single group by works") {
    Given("app with hostname group_by and 20 tasks even distributed on 2 hosts")
    val app = AppDefinition(constraints = Set(makeConstraint("hostname", Operator.GROUP_BY, "")))
    val tasks = 0.to(19).map(num => makeTaskWithHost(s"$num", s"srv${num % 2}")).toSet

    When("10 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks, 10)

    Then("10 tasks got selected and evenly distributed")
    result should have size 10
    val dist = result.groupBy(_.getId.toInt % 2 == 1)
    dist should have size 2
    dist.values.head should have size 5
  }

  test("Select only tasks to kill for an unbalanced distribution") {
    Given("app with hostname group_by and 30 tasks uneven distributed on 2 hosts")
    val app = AppDefinition(constraints = Set(makeConstraint("hostname", Operator.GROUP_BY, "")))
    val tasks = 0.to(19).map(num => makeTaskWithHost(s"$num", s"srv1")) ++
      20.to(29).map(num => makeTaskWithHost(s"$num", s"srv2"))

    When("10 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks.toSet, 10)

    Then("All 10 tasks are from srv1")
    result should have size 10
    result.forall(_.getHost == "srv1") should be(true)
  }

  test("Select tasks to kill for multiple group by works") {
    Given("app with 2 group_by distributions and 40 tasks even distributed")
    val app = AppDefinition(constraints = Set(
      makeConstraint("rack", Operator.GROUP_BY, ""),
      makeConstraint("color", Operator.GROUP_BY, "")))
    val tasks =
      0.to(9).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-1", "color" -> "blue"))) ++
        10.to(19).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-1", "color" -> "green"))) ++
        20.to(29).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-2", "color" -> "blue"))) ++
        30.to(39).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-2", "color" -> "green")))

    When("20 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks.toSet, 20)

    Then("20 tasks got selected and evenly distributed")
    result should have size 20
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "rack-1")) should be(10)
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "rack-2")) should be(10)
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "blue")) should be(10)
    result.count(_.getAttributesList.asScala.exists(_.getText.getValue == "green")) should be(10)
  }

  test("Does not select any task without constraint") {
    Given("app with hostname group_by and 10 tasks even distributed on 5 hosts")
    val app = AppDefinition()
    val tasks = 0.to(9).map(num => makeSampleTask(s"$num", Map("rack" -> "rack-1", "color" -> "blue")))

    When("10 tasks should be selected to kill")
    val result = Constraints.selectTasksToKill(app, tasks.toSet, 5)

    Then("0 tasks got selected")
    result should have size 0
  }

  test("UniqueHostConstraint") {
    val task1_host1 = makeTaskWithHost("task1", "host1")
    val task2_host2 = makeTaskWithHost("task2", "host2")
    val task3_host3 = makeTaskWithHost("task3", "host3")
    val attributes: Set[Attribute] = Set()

    val firstTask = Set()
{'fraction_non_alphanumeric': 0.1369402985074627, 'fraction_numerical': 0.02562189054726368, 'mean_word_length': 4.2214285714285715, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 39, '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': '6032720', 'n_tokens_mistral': 2688, 'n_tokens_neox': 2470, 'n_words': 681}