summaryrefslogtreecommitdiff
path: root/spec/run_oc_pedant.rb
blob: 13cfa5a60872aefe42cbf0e241c49a9e97c5c071 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#!/usr/bin/env ruby
require "json" unless defined?(JSON)
require "bundler"
require "bundler/setup"

require "chef_zero/server"
require "rspec/core"

# This file runs oc-chef-pedant specs and is invoked by `rake pedant`
# and other Rake tasks. Run `rake -T` to list tasks.
#
# Options for oc-chef-pedant and rspec can be specified via
# ENV['PEDANT_OPTS'] and ENV['RSPEC_OPTS'], respectively.
#
# The log level can be specified via ENV['LOG_LEVEL'].
#
# Example:
#
#     $ PEDANT_OPTS="--focus-users --skip-keys" \
#     >   RSPEC_OPTS="--fail-fast --profile 5" \
#     >   LOG_LEVEL=debug \
#     >   rake pedant
#

DEFAULT_SERVER_OPTIONS = {
  port: 8889,
  single_org: false,
}.freeze

DEFAULT_LOG_LEVEL = :warn

def log_level
  return ENV["LOG_LEVEL"].downcase.to_sym if ENV["LOG_LEVEL"]
  return :debug if ENV["DEBUG"]

  DEFAULT_LOG_LEVEL
end

def start_chef_server(opts = {})
  opts = DEFAULT_SERVER_OPTIONS.merge(opts)
  opts[:log_level] = log_level

  ChefZero::Server.new(opts).tap(&:start_background)
end

def start_cheffs_server(chef_repo_path)
  require "chef/version"
  require "chef/config"
  require "chef/chef_fs/config"
  require "chef/chef_fs/chef_fs_data_store"
  require "chef_zero/server"

  Dir.mkdir(chef_repo_path) unless File.exist?(chef_repo_path)

  # 11.6 and below had a bug where it couldn't create the repo children automatically
  if Chef::VERSION.to_f < 11.8
    %w{clients cookbooks data_bags environments nodes roles users}.each do |child|
      Dir.mkdir("#{chef_repo_path}/#{child}") unless File.exist?("#{chef_repo_path}/#{child}")
    end
  end

  # Start the new server
  Chef::Config.repo_mode = "hosted_everything"
  Chef::Config.chef_repo_path = chef_repo_path
  Chef::Config.versioned_cookbooks = true
  chef_fs_config = Chef::ChefFS::Config.new

  data_store = Chef::ChefFS::ChefFSDataStore.new(chef_fs_config.local_fs, chef_fs_config.chef_config)
  data_store = ChefZero::DataStore::V1ToV2Adapter.new(data_store, "pedant-testorg")
  data_store = ChefZero::DataStore::DefaultFacade.new(data_store, "pedant-testorg", false)
  data_store.create(%w{organizations pedant-testorg users}, "pivotal", "{}")
  data_store.set(%w{organizations pedant-testorg groups admins}, '{ "users": [ "pivotal" ] }')
  data_store.set(%w{organizations pedant-testorg groups users}, '{ "users": [ "pivotal" ] }')

  start_chef_server(data_store: data_store)
end

def pedant_args_from_env
  args_from_env("PEDANT_OPTS")
end

def rspec_args_from_env
  args_from_env("RSPEC_OPTS")
end

def args_from_env(key)
  return [] unless ENV[key]

  ENV[key].split
end

begin
  tmpdir = nil
  server =
    if ENV["FILE_STORE"]
      require "tmpdir" unless defined?(Dir.mktmpdir)
      require "chef_zero/data_store/raw_file_store"
      tmpdir = Dir.mktmpdir
      data_store = ChefZero::DataStore::RawFileStore.new(tmpdir, true)
      data_store = ChefZero::DataStore::DefaultFacade.new(data_store, false, false)

      start_chef_server(data_store: data_store)

    elsif ENV["CHEF_FS"]
      require "tmpdir" unless defined?(Dir.mktmpdir)
      tmpdir = Dir.mktmpdir
      start_cheffs_server(tmpdir)

    else
      start_chef_server
    end

  test_secrets = JSON.parse(File.read("spec/support/secrets.json"))
  ENV["SUPERUSER_KEY"] = test_secrets["chef-server"]["superuser_key"]
  ENV["WEBUI_KEY"] = test_secrets["chef-server"]["webui_key"]

  require "rspec/core"
  require "pedant"
  require "pedant/organization"

  # Pedant::Config.rerun = true

  Pedant.config.suite = "api"

  Pedant.config[:config_file] = "spec/support/oc_pedant.rb"

  # Because ChefFS can only ever have one user (pivotal), we can't do most of the
  # tests that involve multiple
  chef_fs_skips = if ENV["CHEF_FS"]
                    [ "--skip-association",
                      "--skip-users",
                      "--skip-organizations",
                      "--skip-multiuser",
                      "--skip-user-keys",
                    ]
                  else
                    []
                  end

  unless Gem::Requirement.new(">= 12.8.0").satisfied_by?(Gem::Version.new(Chef::VERSION))
    chef_fs_skips << "--skip-keys"
  end

  unless Gem::Requirement.new(">= 12.13.19").satisfied_by?(Gem::Version.new(Chef::VERSION))
    chef_fs_skips << "--skip-acl"
    chef_fs_skips << "--skip-cookbook-artifacts"
    chef_fs_skips << "--skip-policies"
  end

  # These things aren't supported by Chef Zero in any mode of operation:
  default_skips = [
    # "the goal is that only authorization, authentication and validation tests
    # are turned off" - @jkeiser
    #
    # ...but we're not there yet

    # Chef Zero does not intend to support validation the way erchef does.
    "--skip-validation",

    # Chef Zero does not intend to support authentication the way erchef does.
    "--skip-authentication",

    # Chef Zero does not intend to support authorization the way erchef does.
    "--skip-authorization",

    # Chef Zero does not intend to support oc_id authentication/authorization
    # the way erchef does.
    "--skip-oc_id",

    # Omnibus tests depend on erchef features that are specific to erchef and
    # bundled in the omnibus package. Currently the only test in this category
    # is for the search reindexing script.
    "--skip-omnibus",

    # USAGs (user-specific association groups) are Authz groups that contain
    # only one user and represent that user's association with an org. Though
    # there are good reasons for them, they don't work well in practice and
    # only the manage console really uses them. Since Chef Zero + Manage is a
    # quite unusual configuration, we're ignoring them.
    "--skip-usags",

    # Chef 12 features not yet 100% supported by Chef Zero

    # chef-zero has some non-removable quirks, such as the fact that files
    # with 255-character names cannot be stored in local mode. This is
    # reserved only for quirks that are *irrevocable* and by design; and
    # should barely be used at all. This is also used to skip the user acl
    # tests from chef-server as the user acls are not supported in chef-zero
    # at this time.
    "--skip-chef-zero-quirks",
  ]

  # The knife tests are very slow and don't give us a lot of extra coverage,
  # so we run them in a different entry in the travis test matrix.
  pedant_args =
    if ENV["PEDANT_KNIFE_TESTS"]
      default_skips + %w{ --focus-knife }
    else
      default_skips + chef_fs_skips + %w{ --skip-knife }
    end

  Pedant.setup(pedant_args + pedant_args_from_env)

  rspec_args = Pedant.config.rspec_args + rspec_args_from_env

  if defined? Chef::ChefFS::FileSystemCache
    RSpec.configure do |c|
      c.before(:each) do
        Chef::ChefFS::FileSystemCache.instance.reset!
      end
    end
  end

  result = RSpec::Core::Runner.run(rspec_args)

  server.stop if server.running?
ensure
  FileUtils.remove_entry_secure(tmpdir) if tmpdir
end

exit(result)