File: tcp_server_spec.cr

package info (click to toggle)
crystal 1.6.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 18,956 kB
  • sloc: javascript: 1,712; sh: 592; cpp: 541; makefile: 243; ansic: 119; python: 105; xml: 32
file content (120 lines) | stat: -rw-r--r-- 3,926 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
{% skip_file if flag?(:wasm32) %}

require "./spec_helper"
require "../../support/win32"

describe TCPServer, tags: "network" do
  describe ".new" do
    each_ip_family do |family, address|
      it "listens on local address" do
        port = unused_local_port

        server = TCPServer.new(address, port)

        server.reuse_port?.should be_false
        server.reuse_address?.should be_true

        local_address = Socket::IPAddress.new(address, port)
        server.local_address.should eq local_address

        server.closed?.should be_false

        server.close

        server.closed?.should be_true
        expect_raises(Socket::Error, "getsockname: ") do
          server.local_address
        end
      end

      it "binds to port 0" do
        server = TCPServer.new(address, 0)

        begin
          server.local_address.address.should eq(address)
          server.local_address.port.should be > 0
        ensure
          server.close
        end
      end

      it "raises when port is negative" do
        error = expect_raises(Socket::Addrinfo::Error) do
          TCPServer.new(address, -12)
        end
        error.os_error.should eq({% if flag?(:linux) %}Errno.new(LibC::EAI_SERVICE){% elsif flag?(:win32) %}WinError::WSATYPE_NOT_FOUND{% else %}Errno.new(LibC::EAI_NONAME){% end %})
      end

      describe "reuse_port" do
        pending_win32 "raises when port is in use" do
          TCPServer.open(address, 0) do |server|
            expect_raises(Socket::BindError, "Could not bind to '#{address}:#{server.local_address.port}': ") do
              TCPServer.open(address, server.local_address.port) { }
            end
          end
        end

        pending_win32 "raises when not binding with reuse_port" do
          TCPServer.open(address, 0, reuse_port: true) do |server|
            expect_raises(Socket::BindError) do
              TCPServer.open(address, server.local_address.port) { }
            end
          end
        end

        pending_win32 "raises when port is not ready to be reused" do
          TCPServer.open(address, 0) do |server|
            expect_raises(Socket::BindError) do
              TCPServer.open(address, server.local_address.port, reuse_port: true) { }
            end
          end
        end

        pending_win32 "binds to used port with reuse_port = true" do
          TCPServer.open(address, 0, reuse_port: true) do |server|
            TCPServer.open(address, server.local_address.port, reuse_port: true) { }
          end
        end
      end
    end

    describe "address resolution" do
      it "binds to localhost" do
        server = TCPServer.new("localhost", unused_local_port)
        server.close
      end

      it "raises when host doesn't exist" do
        err = expect_raises(Socket::Error, "Hostname lookup for doesnotexist.example.org. failed") do
          TCPServer.new("doesnotexist.example.org.", 12345)
        end
        err.os_error.should eq({% if flag?(:win32) %}WinError::WSAHOST_NOT_FOUND{% else %}Errno.new(LibC::EAI_NONAME){% end %})
      end

      it "raises (rather than segfault on darwin) when host doesn't exist and port is 0" do
        err = expect_raises(Socket::Error, "Hostname lookup for doesnotexist.example.org. failed") do
          TCPServer.new("doesnotexist.example.org.", 0)
        end
        err.os_error.should eq({% if flag?(:win32) %}WinError::WSAHOST_NOT_FOUND{% else %}Errno.new(LibC::EAI_NONAME){% end %})
      end
    end

    it "binds to all interfaces" do
      port = unused_local_port
      TCPServer.open(port) do |server|
        server.local_address.port.should eq port
      end
    end
  end

  {% if flag?(:linux) %}
    pending "settings"
  {% else %}
    it "settings" do
      TCPServer.open("::", unused_local_port) do |server|
        (server.recv_buffer_size = 42).should eq 42
        server.recv_buffer_size.should eq 42
      end
    end
  {% end %}
end