summaryrefslogtreecommitdiff
path: root/tests/helpers/couchdb_helper.rb
blob: efb2c2bf1969a1f03fb2ec8d9e7e9550809be31c (plain)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
class LeapTest

  #
  # generates a couchdb url for when couchdb is running
  # remotely and is available via stunnel.
  #
  # example properties:
  #
  # stunnel:
  #   clients:
  #     couch_client:
  #       couch1_5984:
  #         accept_port: 4000
  #         connect: couch1.bitmask.i
  #         connect_port: 15984
  #
  def couchdb_urls_via_stunnel(path="", options=nil)
    path = path.gsub('"', '%22')
    if options && options[:username] && options[:password]
      userpart = "%{username}:%{password}@" % options
    else
      userpart = ""
    end
    assert_property('stunnel.clients.couch_client').values.collect do |stunnel_conf|
      assert port = stunnel_conf['accept_port'], 'Field `accept_port` must be present in `stunnel` property.'
      URLString.new("http://#{userpart}localhost:#{port}#{path}").tap {|url|
        remote_ip_address = TCPSocket.gethostbyname(stunnel_conf['connect']).last
        url.memo = "(via stunnel to %s:%s, aka %s)" % [stunnel_conf['connect'], stunnel_conf['connect_port'], remote_ip_address]
      }
    end
  end

  #
  # generates a couchdb url for accessing couchdb via haproxy
  #
  # example properties:
  #
  # haproxy:
  #   couch:
  #     listen_port: 4096
  #     servers:
  #       panda:
  #         backup: false
  #         host: localhost
  #         port: 4000
  #         weight: 100
  #         writable: true
  #
  def couchdb_url_via_haproxy(path="", options=nil)
    path = path.gsub('"', '%22')
    if options && options[:username] && options[:password]
      userpart = "%{username}:%{password}@" % options
    else
      userpart = ""
    end
    port = assert_property('haproxy.couch.listen_port')
    return URLString.new("http://#{userpart}localhost:#{port}#{path}").tap { |url|
      url.memo = '(via haproxy)'
    }
  end

  #
  # generates a couchdb url for when couchdb is running locally.
  #
  # example properties:
  #
  # couch:
  #   port: 5984
  #
  def couchdb_url_via_localhost(path="", options=nil)
    path = path.gsub('"', '%22')
    port = (options && options[:port]) || assert_property('couch.port')
    if options && options[:username]
      password = property("couch.users.%{username}.password" % options)
      userpart = "%s:%s@" % [options[:username], password]
    else
      userpart = ""
    end
    return URLString.new("http://#{userpart}localhost:#{port}#{path}").tap { |url|
      url.memo = '(via direct localhost connection)'
    }
  end

  #
  # returns a single url for accessing couchdb
  #
  def couchdb_url(path="", options=nil)
    if property('couch.port')
      couchdb_url_via_localhost(path, options)
    elsif property('stunnel.clients.couch_client')
      couchdb_urls_via_stunnel(path, options).first
    end
  end

  #
  # returns an array of urls for accessing couchdb
  #
  def couchdb_urls(path="", options=nil)
    if property('couch.port')
      [couchdb_url_via_localhost(path, options)]
    elsif property('stunnel.clients.couch_client')
      couchdb_urls_via_stunnel(path, options)
    end
  end

  def assert_destroy_user_db(user_id, options=nil)
    db_name = "user-#{user_id}"
    url = couchdb_url("/#{db_name}", options)
    http_options = {:ok_codes => [200, 404]} # ignore missing dbs
    assert_delete(url, nil, http_options)
  end

  def assert_create_user_db(user_id, options=nil)
    db_name = "user-#{user_id}"
    url = couchdb_url("/#{db_name}", options)
    http_options = {:ok_codes => [200, 404]} # ignore missing dbs
    assert_put(url, nil, :format => :json) do |body|
      assert response = JSON.parse(body), "PUT response should be JSON"
      assert response["ok"], "PUT response should be OK"
    end
  end

  #
  # returns true if the per-user db created by soledad-server exists.
  #
  def user_db_exists?(user_id, options=nil)
    options = {:username => 'admin'}.merge(options || {})
    db_name = "user-#{user_id}"
    url = couchdb_url("/#{db_name}", options)
    get(url) do |body, response, error|
      if response.nil?
        fail "could not query couchdb #{url}: #{error}\n#{body}"
      elsif response.code.to_i == 200
        return true
      elsif response.code.to_i == 404
        return false
      else
        fail ["could not query couchdb #{url}: expected response code 200 or 404, but got #{response.code}.", error, body].compact.join("\n")
      end
    end
  end

end