Skip to content
Snippets Groups Projects
Part7Test.scala 2.44 KiB
Newer Older
Matt Bovel's avatar
Matt Bovel committed
package midterm22

import org.junit.*
import org.junit.Assert.*
import instrumentation.*

class Part7Test:
  @Test
  def testNicManagerSequential() =
    val nicsManager = NICManager(4)
    assertEquals((0, 1), nicsManager.assignNICs())
    assertEquals((2, 3), nicsManager.assignNICs())

  @Test
  def testQuestion22() =
    testNicManagerParallel(2, 3)
Matt Bovel's avatar
Matt Bovel committed

Matt Bovel's avatar
Matt Bovel committed
  @Test
  def testQuestion23() =
    val nicsManager = NICManager(2)

    // Thread 1
    assertEquals((0, 1), nicsManager.assignNICs())
    nicsManager.nics(0).assigned = false
    nicsManager.nics(1).assigned = false

    // Thread 2
    assertEquals((0, 1), nicsManager.assignNICs())
    nicsManager.nics(0).assigned = false
    nicsManager.nics(1).assigned = false

  @Test
  def testQuestion24() =
    testNicManagerParallel(3, 2, true)
Matt Bovel's avatar
Matt Bovel committed

Matt Bovel's avatar
Matt Bovel committed
  @Test
  def testQuestion24NotLimitingRecvNICs() =
    TestUtils.assertMaybeDeadlock(
Matt Bovel's avatar
Matt Bovel committed
      testNicManagerParallel(3, 2)
Matt Bovel's avatar
Matt Bovel committed
    )

  def testNicManagerParallel(
      threads: Int,
      nics: Int,
      limitRecvNICs: Boolean = false
  ) =
    TestHelper.testManySchedules(
      threads,
      scheduler =>
        val nicsManager = ScheduledNicsManager(nics, scheduler)
Matt Bovel's avatar
Matt Bovel committed
        val tasks =
          for i <- 0 until threads yield () =>
            // Thread i
            val (recvNIC, sendNIC) = nicsManager.assignNICs(limitRecvNICs)
Matt Bovel's avatar
Matt Bovel committed
            // Do something with NICs...
Matt Bovel's avatar
Matt Bovel committed
            // Un-assign NICs
            nicsManager.nics(recvNIC).assigned = false
            nicsManager.nics(sendNIC).assigned = false
Matt Bovel's avatar
Matt Bovel committed
        (
          tasks.toList,
          results =>
            if nicsManager.nics.count(_.assigned) != 0 then
              (false, f"All NICs should have been released.")
            else (true, "")
        )
    )

  class ScheduledNicsManager(n: Int, scheduler: Scheduler)
      extends NICManager(n):
    class ScheduledNIC(
        _index: Int,
        _assigned: Boolean,
        val scheduler: Scheduler
    ) extends NIC(_index, _assigned)
        with MockedMonitor:
      override def index = scheduler.exec { super.index }(
        "",
        Some(res => f"read NIC.index == $res")
      )
      override def assigned = scheduler.exec { super.assigned }(
        "",
        Some(res => f"read NIC.assigned == $res")
      )
Matt Bovel's avatar
Matt Bovel committed
      override def assigned_=(v: Boolean) =
        scheduler.exec { super.assigned = v }(
          f"write NIC.assigned = $v"
        )
Matt Bovel's avatar
Matt Bovel committed
    override val nics =
      (for i <- 0 until n yield ScheduledNIC(i, false, scheduler)).toList