Project

General

Profile

Download (6.28 KB) Statistics
| Branch: | Tag: | Revision:

foreman-docker / test / units / registry_api_test.rb @ c69bcf98

1
require 'test_plugin_helper'
2

    
3
class RegistryApiTest < ActiveSupport::TestCase
4
  let(:url) { 'http://dockerregistry.com:5000' }
5
  subject { Service::RegistryApi.new(url: url) }
6

    
7
  describe '#connection' do
8
    test 'returns a Docker::Connection' do
9
      assert_equal Docker::Connection, subject.connection.class
10
    end
11

    
12
    test 'the connection has the same url' do
13
      assert_equal url, subject.connection.url
14
    end
15

    
16
    test 'it requests json' do
17
      assert_equal 'application/json', subject.connection.options[:headers]['Content-Type']
18
    end
19

    
20
    context 'authentication is set' do
21
      let(:user) { 'username' }
22
      let(:password) { 'secretpassword' }
23

    
24
      subject do
25
        Service::RegistryApi.new(
26
          :url => url,
27
          :password => password,
28
          :user => user
29
        )
30
      end
31

    
32
      test 'it sets the same user and password' do
33
        assert_equal user, subject.connection.options[:user]
34
        assert_equal password, subject.connection.options[:password]
35
      end
36
    end
37

    
38
    context 'verify ssl is set' do
39
      let(:verify_ssl) { [true, false].sample }
40
      subject { Service::RegistryApi.new(url: url, verify_ssl: verify_ssl) }
41

    
42
      test 'it passes it as ssl_verify_peer' do
43
        assert_equal verify_ssl, subject.connection.options[:ssl_verify_peer]
44
      end
45
    end
46
  end
47

    
48
  describe '#get' do
49
    let(:path) { '/v1/search' }
50
    let(:json) { '{}' }
51

    
52
    test 'calls get on #connection' do
53
      subject.connection
54
             .expects(:get).at_least_once
55
             .returns(json)
56

    
57
      subject.get(path)
58
    end
59

    
60
    test 'returns a parsed json' do
61
      subject.connection.stubs(:get).returns(json)
62
      assert_equal JSON.parse(json), subject.get(path)
63
    end
64

    
65
    # Docker::Connection is used and meant for the Docker,
66
    # not the Registry API therefore it is required
67
    # to override the path via options
68
    test 'sets the path as an option not param for Docker::Connection#get' do
69
      subject.connection.stubs(:get) do |path_param, _, options|
70
        refute_equal path, path_param
71
        assert_equal path, options[:path]
72
      end.returns(json)
73

    
74
      subject.get(path)
75
    end
76

    
77
    # Docker Hub will return a 503 when a 'Host' header includes a port.
78
    # Omitting default ports (an Excon option) solves the issue
79
    test 'sets omit_default_port to true' do
80
      subject.connection.stubs(:get) do |_, _, options|
81
        assert options[:omit_default_port]
82
      end.returns(json)
83

    
84
      subject.get(path)
85
    end
86

    
87
    test 'returns the response raw body if it is not JSON' do
88
      response = 'This is not JSON'
89
      subject.connection.stubs(:get)
90
             .returns(response)
91
      assert_equal response, subject.get('/v1/')
92
    end
93
  end
94

    
95
  describe '#search' do
96
    let(:path) { '/v1/search' }
97
    let(:query) { 'centos' }
98

    
99
    test "calls #get with path and query" do
100
      subject.expects(:get).with(path, q: query) do |path_param, params|
101
        assert_equal path, path_param
102
        assert_equal query, params[:q]
103
      end.returns({})
104

    
105
      subject.search(query)
106
    end
107

    
108
    test "falls back to #catalog if #get fails" do
109
      subject.expects(:catalog).with(query)
110

    
111
      subject.expects(:get).with(path, q: query)
112
             .raises('Error')
113

    
114
      subject.search(query)
115
    end
116
  end
117

    
118
  describe '#catalog' do
119
    let(:path) { '/v2/_catalog' }
120
    let(:query) { 'centos' }
121
    let(:catalog) { { 'repositories' => ['centos', 'fedora'] } }
122

    
123
    setup do
124
      subject.stubs(:get).returns(catalog)
125
    end
126

    
127
    test "calls #get with path" do
128
      subject.expects(:get).with(path)
129
             .returns(catalog)
130

    
131
      subject.catalog(query)
132
    end
133

    
134
    test 'returns {"name" => value} pairs' do
135
      result = subject.catalog(query)
136
      assert_equal({ "name" => query }, result.first)
137
    end
138

    
139
    test 'only give back matching results' do
140
      result = subject.catalog('fedora')
141
      assert_match(/^fedora/, result.first['name'])
142
    end
143
  end
144

    
145
  describe '#tags' do
146
    let(:query) { 'alpine' }
147
    let(:path) { "/v1/repositories/#{query}/tags" }
148

    
149
    test "calls #get with path" do
150
      subject.expects(:get).with(path)
151
      subject.tags(query)
152
    end
153

    
154
    test "falls back to #tags_v2 if #get fails" do
155
      subject.expects(:get).with(path)
156
             .raises('Error')
157

    
158
      subject.expects(:tags_v2).with(query)
159
      subject.tags(query)
160
    end
161

    
162
    # https://registry.access.redhat.com returns a hash not an array
163
    test 'handles a hash response correctly' do
164
      tags_hash = {
165
        "7.0-21" => "e1f5733f050b2488a17b7630cb038bfbea8b7bdfa9bdfb99e63a33117e28d02f",
166
        "7.0-23" => "bef54b8f8a2fdd221734f1da404d4c0a7d07ee9169b1443a338ab54236c8c91a",
167
        "7.0-27" => "8e6704f39a3d4a0c82ec7262ad683a9d1d9a281e3c1ebbb64c045b9af39b3940"
168
      }
169
      subject.expects(:get).with(path)
170
             .returns(tags_hash)
171
      assert_equal '7.0-21', subject.tags(query).first['name']
172
    end
173
  end
174

    
175
  describe '#tags for API v2' do
176
    let(:query) { 'debian' }
177
    let(:v1_path) { "/v1/repositories/#{query}/tags" }
178
    let(:path) { "/v2/#{query}/tags/list" }
179
    let(:tags) { { 'tags' => ['jessy', 'woody'] } }
180

    
181
    setup do
182
      subject.stubs(:get).with(v1_path)
183
             .raises('404 Not found')
184
    end
185

    
186
    test 'calls #get with path' do
187
      subject.expects(:get).with(path)
188
             .returns(tags)
189
      subject.tags(query)
190
    end
191

    
192
    test 'returns {"name" => value } pairs ' do
193
      subject.stubs(:get).with(path).returns(tags)
194
      result = subject.tags(query)
195
      assert_equal tags['tags'].first, result.first['name']
196
    end
197
  end
198

    
199
  describe '#ok?' do
200
    test 'calls the API via #get with /v1/' do
201
      params = subject.send(:default_connection_options)
202
                      .merge(subject.send(:credentials))
203
                      .merge(path: '/v1/')
204
      subject.connection.expects(:get)
205
             .with('/', nil, params)
206
             .returns('Docker Registry API')
207
      assert subject.ok?
208
    end
209

    
210
    test 'calls #get with /v2/ if /v1/fails' do
211
      subject.stubs(:get).with('/v1/')
212
             .raises('404 page not found')
213
      subject.expects(:get).with('/v2/')
214
             .returns({})
215
      assert subject.ok?
216
    end
217
  end
218

    
219
  describe '.docker_hub' do
220
    subject { Service::RegistryApi }
221

    
222
    test 'returns an instance for Docker Hub' do
223
      result = subject.docker_hub
224
      assert_equal Service::RegistryApi::DOCKER_HUB, result.url
225
    end
226
  end
227
end