You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: test_server.rb
    path of file: ./repos/artichoke/artichoke-backend/vendor/ruby/tool/test/webrick
    
    the code of the file until where you have to start completion: # frozen_string_literal: false
require "test/unit"
require "tempfile"
require "webrick"
require_relative "utils"

class TestWEBrickServer < Test::Unit::TestCase
  class Echo < WEBrick::GenericServer
    def run(sock)
      while line = sock.gets
        sock << line
      end
    end
  end

  def test_server
    TestWEBrick.start_server(Echo){|server, addr, port, log|
      TCPSocket.open(addr, port){|sock|
        sock.puts("foo"); assert_equal("foo\n", sock.gets, log.call)
        sock.puts("bar"); assert_equal("bar\n", sock.gets, log.call)
        sock.puts("baz"); assert_equal("baz\n", sock.gets, log.call)
        sock.puts("qux"); assert_equal("qux\n", sock.gets, log.call)
      }
    }
 
    
  def test_port_numbers
    config = {
      :BindAddress => '0.0.0.0',
      :Logger => WEBrick::Log.new([], WEBrick::BasicLog::WARN),
    }

    ports = [0, "0"]

    ports.each do |port|
      config[:Port]= port
      server = WEBrick::GenericServer.new(config)
      server_thread = Thread.start { server.start }
      client_thread = Thread.start {
        sleep 0.1 until server.status == :Running || !server_thread.status
        server_port = server.listeners[0].addr[1]
        server.stop
        assert_equal server.config[:Port], server_port
        sleep 0.1 until server.status == :Stop || !server_thread.status
      }
      assert_join_threads([client_thread, server_thread])
    end

    assert_raise(ArgumentError) do
      config[:Port]= "FOO"
      WEBrick::GenericServer.new(config)
    end
  end