Skip to content

Commit 7a1d089

Browse files
committed
Add SocketAllocationSpec
1 parent 84d64f9 commit 7a1d089

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package protocbridge.frontend
2+
import org.scalatest.flatspec.AnyFlatSpec
3+
import org.scalatest.matchers.must.Matchers
4+
5+
import java.lang.management.ManagementFactory
6+
import java.net.ServerSocket
7+
import scala.collection.mutable
8+
import scala.sys.process._
9+
import scala.util.{Failure, Success, Try}
10+
11+
class SocketAllocationSpec extends AnyFlatSpec with Matchers {
12+
it must "allocate an unused port" in {
13+
val repeatCount = 100000
14+
val portConflictCount = mutable.Map[Int, Int]()
15+
16+
val currentPid = getCurrentPid
17+
18+
for (i <- 1 to repeatCount) {
19+
if (i % 100 == 1) println(s"Running iteration $i of $repeatCount")
20+
21+
val serverSocket = new ServerSocket(0) // Bind to any available port.
22+
try {
23+
val port = serverSocket.getLocalPort
24+
Try {
25+
s"lsof -i :$port -t".!!.trim
26+
} match {
27+
case Success(output) =>
28+
if (output.nonEmpty) {
29+
val pids = output.split("\n").filterNot(_.contains(currentPid.toString))
30+
if (pids.nonEmpty) {
31+
System.err.println("Port conflict detected on port " + port + " with PIDs: " + pids.mkString(", "))
32+
portConflictCount(port) = portConflictCount.getOrElse(port, 0) + 1
33+
}
34+
}
35+
case Failure(_) => // Ignore failure and continue
36+
}
37+
} finally {
38+
serverSocket.close()
39+
}
40+
}
41+
42+
assert(portConflictCount.isEmpty, s"Found the following ports in use out of $repeatCount: $portConflictCount")
43+
}
44+
45+
private def getCurrentPid: Int = {
46+
val jvmName = ManagementFactory.getRuntimeMXBean.getName
47+
val pid = jvmName.split("@")(0)
48+
pid.toInt
49+
}
50+
}

0 commit comments

Comments
 (0)