vagrant-skytap 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,9 +9,7 @@ module VagrantPlugins
9
9
  # This action is called to halt the remote machine.
10
10
  def self.action_halt
11
11
  Vagrant::Action::Builder.new.tap do |b|
12
- b.use ConfigValidate
13
- b.use InitializeAPIClient
14
- b.use FetchEnvironment
12
+ b.use action_fetch_environment
15
13
  b.use Call, ExistenceCheck do |env1, b1|
16
14
  case result = env1[:result]
17
15
  when :missing_environment, :missing_vm, :no_vms
@@ -26,9 +24,7 @@ module VagrantPlugins
26
24
  # This action is called to suspend the remote machine.
27
25
  def self.action_suspend
28
26
  Vagrant::Action::Builder.new.tap do |b|
29
- b.use ConfigValidate
30
- b.use InitializeAPIClient
31
- b.use FetchEnvironment
27
+ b.use action_fetch_environment
32
28
  b.use Call, ExistenceCheck do |env1, b1|
33
29
  case result = env1[:result]
34
30
  when :missing_environment, :missing_vm, :no_vms
@@ -43,9 +39,7 @@ module VagrantPlugins
43
39
  # This action is called to terminate the remote machine.
44
40
  def self.action_destroy
45
41
  Vagrant::Action::Builder.new.tap do |b|
46
- b.use ConfigValidate
47
- b.use InitializeAPIClient
48
- b.use FetchEnvironment
42
+ b.use action_fetch_environment
49
43
  b.use Call, ExistenceCheck do |env, b1|
50
44
  case existence_state = env[:result]
51
45
  when :missing_environment, :no_vms
@@ -79,9 +73,7 @@ module VagrantPlugins
79
73
  # This action is called when `vagrant provision` is called.
80
74
  def self.action_provision
81
75
  Vagrant::Action::Builder.new.tap do |b|
82
- b.use ConfigValidate
83
- b.use InitializeAPIClient
84
- b.use FetchEnvironment
76
+ b.use action_fetch_environment
85
77
  b.use Call, ExistenceCheck do |env, b1|
86
78
  case result = env[:result]
87
79
  when :missing_environment, :missing_vm, :no_vms
@@ -115,9 +107,7 @@ module VagrantPlugins
115
107
  # key.
116
108
  def self.action_read_ssh_info
117
109
  Vagrant::Action::Builder.new.tap do |b|
118
- b.use ConfigValidate
119
- b.use InitializeAPIClient
120
- b.use FetchEnvironment
110
+ b.use action_fetch_environment
121
111
  b.use ReadSSHInfo
122
112
  end
123
113
  end
@@ -127,9 +117,7 @@ module VagrantPlugins
127
117
  # key.
128
118
  def self.action_read_state
129
119
  Vagrant::Action::Builder.new.tap do |b|
130
- b.use ConfigValidate
131
- b.use InitializeAPIClient
132
- b.use FetchEnvironment
120
+ b.use action_fetch_environment
133
121
  #TODO:NLA Can this whole action be removed?
134
122
  b.use ReadState
135
123
  end
@@ -138,9 +126,7 @@ module VagrantPlugins
138
126
  # This action is called to SSH into the machine.
139
127
  def self.action_ssh
140
128
  Vagrant::Action::Builder.new.tap do |b|
141
- b.use ConfigValidate
142
- b.use InitializeAPIClient
143
- b.use FetchEnvironment
129
+ b.use action_fetch_environment
144
130
  b.use Call, ExistenceCheck do |env1, b1|
145
131
  case result = env1[:result]
146
132
  when :missing_environment, :missing_vm, :no_vms
@@ -154,9 +140,7 @@ module VagrantPlugins
154
140
 
155
141
  def self.action_ssh_run
156
142
  Vagrant::Action::Builder.new.tap do |b|
157
- b.use ConfigValidate
158
- b.use InitializeAPIClient
159
- b.use FetchEnvironment
143
+ b.use action_fetch_environment
160
144
  b.use Call, ExistenceCheck do |env1, b1|
161
145
  case result = env1[:result]
162
146
  when :missing_environment, :missing_vm, :no_vms
@@ -185,15 +169,12 @@ module VagrantPlugins
185
169
 
186
170
  def self.action_resume
187
171
  Vagrant::Action::Builder.new.tap do |b|
188
- Vagrant::Action::Builder.new.tap do |b|
189
- b.use InitializeAPIClient
190
- b.use FetchEnvironment
191
- b.use Call, IsSuspended do |env, b1|
192
- if env[:result]
193
- b1.use MessageResuming
194
- b1.use RunVm
195
- b1.use WaitForCommunicator
196
- end
172
+ b.use action_fetch_environment
173
+ b.use Call, IsSuspended do |env, b1|
174
+ if env[:result]
175
+ b1.use MessageResuming
176
+ b1.use RunVm
177
+ b1.use WaitForCommunicator
197
178
  end
198
179
  end
199
180
  end
@@ -209,9 +190,7 @@ module VagrantPlugins
209
190
  def self.action_create
210
191
  Vagrant::Action::Builder.new.tap do |b|
211
192
  b.use HandleBox
212
- b.use ConfigValidate
213
- b.use InitializeAPIClient
214
- b.use FetchEnvironment
193
+ b.use action_fetch_environment
215
194
  b.use Call, ExistenceCheck do |env, b1|
216
195
  case result = env[:result]
217
196
  when :missing_environment
@@ -277,9 +256,7 @@ module VagrantPlugins
277
256
 
278
257
  def self.action_reload
279
258
  Vagrant::Action::Builder.new.tap do |b|
280
- b.use ConfigValidate
281
- b.use InitializeAPIClient
282
- b.use FetchEnvironment
259
+ b.use action_fetch_environment
283
260
  b.use Call, ExistenceCheck do |env, b1|
284
261
  case env[:result]
285
262
  when :missing_environment, :missing_vm, :no_vms
@@ -296,6 +273,14 @@ module VagrantPlugins
296
273
  end
297
274
  end
298
275
 
276
+ def self.action_fetch_environment
277
+ Vagrant::Action::Builder.new.tap do |b|
278
+ b.use ConfigValidate
279
+ b.use InitializeAPIClient
280
+ b.use FetchEnvironment
281
+ end
282
+ end
283
+
299
284
  # The autoload farm
300
285
  action_root = Pathname.new(File.expand_path("../action", __FILE__))
301
286
  autoload :StoreExtraData, action_root.join("store_extra_data")
@@ -4,6 +4,8 @@ require 'vagrant-skytap/environment_properties'
4
4
  require 'vagrant-skytap/api/resource'
5
5
  require 'vagrant-skytap/api/vm'
6
6
  require 'vagrant-skytap/api/network'
7
+ require 'vagrant-skytap/api/publish_set'
8
+
7
9
  require_relative 'runstate_operations'
8
10
 
9
11
  module VagrantPlugins
@@ -54,8 +56,12 @@ module VagrantPlugins
54
56
  end
55
57
  end
56
58
 
59
+ def get_vms_by_id(ids=[])
60
+ vms.select{|vm| ids.include?(vm.id)}
61
+ end
62
+
57
63
  def get_vm_by_id(id)
58
- vms.find{|vm|vm.id == id}
64
+ get_vms_by_id([id]).first
59
65
  end
60
66
 
61
67
  def current_vm
@@ -68,6 +74,12 @@ module VagrantPlugins
68
74
  end
69
75
  end
70
76
 
77
+ def publish_sets
78
+ @publish_sets ||= (get_api_attribute('publish_sets') || []).collect do |ps_attrs|
79
+ PublishSet.new(ps_attrs, self, env)
80
+ end
81
+ end
82
+
71
83
  def region
72
84
  get_api_attribute('region')
73
85
  end
@@ -75,6 +87,7 @@ module VagrantPlugins
75
87
  def refresh(attrs)
76
88
  @vms = nil
77
89
  @networks = nil
90
+ @publish_sets = nil
78
91
  super
79
92
  end
80
93
 
@@ -104,6 +117,11 @@ module VagrantPlugins
104
117
  self.class.check_vm_before_adding(env, vm)
105
118
  end
106
119
 
120
+ def create_publish_set(attrs={})
121
+ resp = api_client.post("#{url}/publish_sets", JSON.dump(attrs))
122
+ PublishSet.new(JSON.load(resp.body), self, env)
123
+ end
124
+
107
125
  def properties
108
126
  @properties ||= EnvironmentProperties.new(env[:machine].env.local_data_path)
109
127
  end
@@ -0,0 +1,36 @@
1
+ require 'vagrant-skytap/api/resource'
2
+
3
+ module VagrantPlugins
4
+ module Skytap
5
+ module API
6
+ class PublishSet < Resource
7
+
8
+ attr_reader :environment
9
+ reads :id, :url, :desktops_url
10
+
11
+ def initialize(attrs, environment, env)
12
+ super
13
+ @environment = environment
14
+ end
15
+
16
+ def password_protected?
17
+ # password attribute contains asterisks or null
18
+ get_api_attribute('password').present?
19
+ end
20
+
21
+ def vm_ids
22
+ vm_refs = get_api_attribute("vms").collect{|ref| ref['vm_ref']}
23
+ vm_refs.collect{|ref| ref.match(/\/vms\/(\d+)/)}.compact.map{|match| match[1]}
24
+ end
25
+
26
+ def vms
27
+ environment.get_vms_by_id(vm_ids)
28
+ end
29
+
30
+ def delete
31
+ api_client.delete(url)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -12,7 +12,7 @@ module VagrantPlugins
12
12
  attr_reader :provider_config
13
13
  attr_reader :environment
14
14
 
15
- reads :id, :interfaces, :credentials
15
+ reads :id, :interfaces, :credentials, :name
16
16
 
17
17
  class << self
18
18
  def fetch(env, url)
@@ -0,0 +1,14 @@
1
+ module VagrantPlugins
2
+ module Skytap
3
+ module Cap
4
+ module PublicAddress
5
+ def self.public_address(machine)
6
+ if machine.state.id == :running
7
+ ssh_info = machine.ssh_info
8
+ ssh_info[:host] if ssh_info
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ module VagrantPlugins
2
+ module Skytap
3
+ module Command
4
+ module Helpers
5
+ def target_vms
6
+ @target_vms ||= [].tap do |ret|
7
+ with_target_vms{|machine| ret << machine}
8
+ end
9
+ end
10
+
11
+ def fetch_environment
12
+ if machine = target_vms.first
13
+ @environment ||= machine.action(:fetch_environment)[:environment]
14
+ end
15
+ end
16
+
17
+ def target_skytap_vms
18
+ fetch_environment.get_vms_by_id(target_vms.collect(&:id))
19
+ end
20
+
21
+ def machine_names(vm_ids)
22
+ target_vms.select{|m| vm_ids.include?(m.id)}.collect{|m| m.name.to_s}
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+
30
+
@@ -0,0 +1,65 @@
1
+ require 'optparse'
2
+ require 'vagrant-skytap/command/helpers'
3
+
4
+ module VagrantPlugins
5
+ module Skytap
6
+ module Command
7
+ module PublishUrl
8
+ class Create < Vagrant.plugin("2", :command)
9
+ include Command::Helpers
10
+
11
+ def execute
12
+ options = {}
13
+
14
+ opts = OptionParser.new do |o|
15
+ o.banner = "Usage: vagrant publish-url create [options]"
16
+ o.separator ""
17
+ o.separator "Options:"
18
+ o.separator ""
19
+
20
+
21
+ o.on("-p", "--password PASSWORD", "Set a password for the publish set") do |p|
22
+ options[:password] = p
23
+ end
24
+
25
+ o.on("-np", "--no-password", "Do not set a password") do |np|
26
+ options[:no_password] = true
27
+ end
28
+
29
+ o.separator ""
30
+ o.separator "You will be prompted for a password unless one of the"
31
+ o.separator "options --password or --no-password have been provided."
32
+ o.separator "Blank passwords are allowed."
33
+ o.separator ""
34
+ end
35
+
36
+ return unless argv = parse_options(opts)
37
+
38
+ unless options[:no_password] || password = options[:password]
39
+ password = @env.ui.ask("Password for publish set (will be hidden; blank for no password): ", echo: false)
40
+ end
41
+ password ||= ""
42
+
43
+ ps = fetch_environment.create_publish_set(
44
+ name: "Vagrant publish set",
45
+ publish_set_type: "single_url",
46
+ vms: target_skytap_vms.collect do |vm|
47
+ {
48
+ vm_ref: vm.url,
49
+ access: "run_and_use",
50
+ }
51
+ end,
52
+ password: password
53
+ )
54
+ @logger.debug("New publish set: #{ps.url}")
55
+
56
+ @env.ui.info(I18n.t("vagrant_skytap.commands.publish_urls.created", url: ps.desktops_url))
57
+
58
+ # Success, exit status 0
59
+ 0
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ require 'optparse'
2
+ require 'vagrant-skytap/command/helpers'
3
+
4
+ module VagrantPlugins
5
+ module Skytap
6
+ module Command
7
+ module PublishUrl
8
+ class Delete < Vagrant.plugin("2", :command)
9
+ include Command::Helpers
10
+
11
+ def execute
12
+ options = {}
13
+
14
+ opts = OptionParser.new do |o|
15
+ o.separator ""
16
+ o.separator "Deletes all published URLs for this project, including any"
17
+ o.separator "created through the Skytap UI."
18
+
19
+ o.banner = "Usage: vagrant publish-url delete [options]"
20
+ o.separator ""
21
+ o.separator "Options:"
22
+ o.separator ""
23
+
24
+ o.on("-f", "--force", "Delete without prompting") do |f|
25
+ options[:force] = f
26
+ end
27
+ end
28
+
29
+ return unless argv = parse_options(opts)
30
+
31
+ if publish_sets = fetch_environment.publish_sets.presence
32
+ unless options[:force]
33
+ confirm = @env.ui.ask(I18n.t("vagrant_skytap.commands.publish_urls.confirm_delete"))
34
+ return unless confirm.downcase == 'y'
35
+ end
36
+ publish_sets.each(&:delete)
37
+ @env.ui.info(I18n.t("vagrant_skytap.commands.publish_urls.deleted"))
38
+ else
39
+ @env.ui.info(I18n.t("vagrant_skytap.commands.publish_urls.empty_list"))
40
+ end
41
+
42
+ # Success, exit status 0
43
+ 0
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,76 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module Skytap
5
+ module Command
6
+ module PublishUrl
7
+ class Root < Vagrant.plugin("2", :command)
8
+ def self.synopsis
9
+ "manages published URLs"
10
+ end
11
+
12
+ def initialize(argv, env)
13
+ super
14
+
15
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
16
+
17
+ @subcommands = Vagrant::Registry.new
18
+ @subcommands.register(:create) do
19
+ require_relative "create"
20
+ Create
21
+ end
22
+
23
+ @subcommands.register(:delete) do
24
+ require_relative "delete"
25
+ Delete
26
+ end
27
+
28
+ @subcommands.register(:show) do
29
+ require_relative "show"
30
+ Show
31
+ end
32
+ end
33
+
34
+ def execute
35
+ if @main_args.include?("-h") || @main_args.include?("--help")
36
+ # Print the help for all the box commands.
37
+ return help
38
+ end
39
+
40
+ # If we reached this far then we must have a subcommand. If not,
41
+ # then we also just print the help and exit.
42
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
43
+ return help if !command_class || !@sub_command
44
+ @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
45
+
46
+ # Initialize and execute the command class
47
+ command_class.new(@sub_args, @env).execute
48
+ end
49
+
50
+ # Prints the help out for this command
51
+ def help
52
+ opts = OptionParser.new do |opts|
53
+ opts.banner = "Usage: vagrant publish-url <subcommand> [<args>]"
54
+ opts.separator ""
55
+ opts.separator "Available subcommands:"
56
+
57
+ # Add the available subcommands as separators in order to print them
58
+ # out as well.
59
+ keys = []
60
+ @subcommands.each { |key, value| keys << key.to_s }
61
+
62
+ keys.sort.each do |key|
63
+ opts.separator " #{key}"
64
+ end
65
+
66
+ opts.separator ""
67
+ opts.separator "For help on any individual subcommand run `vagrant publish-url <subcommand> -h`"
68
+ end
69
+
70
+ @env.ui.info(opts.help, prefix: false)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,29 @@
1
+ require 'vagrant-skytap/command/helpers'
2
+
3
+ module VagrantPlugins
4
+ module Skytap
5
+ module Command
6
+ module PublishUrl
7
+ class Show < Vagrant.plugin("2", :command)
8
+ include Command::Helpers
9
+
10
+ def execute
11
+ if publish_sets = fetch_environment.publish_sets.presence
12
+ results = publish_sets.collect do |ps|
13
+ "#{ps.desktops_url || 'n/a'}\n" \
14
+ " VMs: #{machine_names(ps.vm_ids).join(', ').presence || '(none)'}" \
15
+ " Password protected? #{ps.password_protected? ? 'yes' : 'no'}"
16
+ end
17
+ @env.ui.info(I18n.t("vagrant_skytap.commands.publish_urls.list", publish_urls: results.join("\n")))
18
+ else
19
+ @env.ui.info(I18n.t("vagrant_skytap.commands.publish_urls.empty_list"))
20
+ end
21
+
22
+ # Success, exit status 0
23
+ 0
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -36,7 +36,17 @@ module VagrantPlugins
36
36
 
37
37
  command("up", primary: true) do
38
38
  require_relative "command/up"
39
- Command::Up
39
+ Skytap::Command::Up
40
+ end
41
+
42
+ command("publish-url", primary: true) do
43
+ require_relative "command/publish_url/root"
44
+ Skytap::Command::PublishUrl::Root
45
+ end
46
+
47
+ provider_capability(:skytap, :public_address) do
48
+ require_relative "cap/public_address"
49
+ Cap::PublicAddress
40
50
  end
41
51
 
42
52
  # This initializes the internationalization strings.
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Skytap
3
- VERSION = "0.1.8"
3
+ VERSION = "0.1.9"
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -136,3 +136,32 @@ en:
136
136
  long_busy: |-
137
137
  The Skytap instance is busy. Wait for the current operation to complete.
138
138
 
139
+ commands:
140
+ publish_urls:
141
+ list: |-
142
+ The VMs in this Skytap environment can be accessed through the
143
+ following published URL(s):
144
+ %{publish_urls}
145
+ empty_list: |-
146
+ No published URLs were found for this Skytap environment. Run
147
+ `vagrant publish-url create` to create one.
148
+ created: |-
149
+ This Skytap environment (or the specified subset of VMs) can be
150
+ accessed at the following URL: %{url}
151
+ Note that anyone with this URL and password will have full control
152
+ of the VMs until the published URL is deleted. (Finer-grained
153
+ control is available through the Skytap UI.)
154
+ already_exists: |-
155
+ There is already a published URL for this Skytap environment.
156
+ To modify the published URL, please delete it and create a new
157
+ one. (Finer-grained control is available through the Skytap UI.)
158
+ confirm_delete: |-
159
+ This action will delete ALL published URLs for this Skytap
160
+ environment, including those created through the Skytap UI.
161
+ Are you sure you wish to do this? [yN]
162
+ deleted: |-
163
+ All published URLs for this Skytap environment (including those
164
+ created through the Skytap UI) have been deleted. Users cannot
165
+ manage these VMs, or access them through SmartClient, unless they
166
+ have a Skytap user account with appropriate permissions.
167
+
data/spec/unit/base.rb CHANGED
@@ -23,10 +23,7 @@ require "unit/support/shared/capability_helpers_context"
23
23
  require "unit/support/shared/plugin_command_context"
24
24
  require "unit/support/shared/skytap_context"
25
25
 
26
- require "vagrant-skytap/core_ext/object/blank"
27
- require "vagrant-skytap/core_ext/object/tap"
28
- require "vagrant-skytap/core_ext/try"
29
- require "vagrant-skytap/plugin"
26
+ require "vagrant-skytap"
30
27
 
31
28
  # Do not buffer output
32
29
  $stdout.sync = true
@@ -1,7 +1,6 @@
1
1
  require_relative 'base'
2
2
  require "vagrant-skytap/api/environment"
3
3
  require "vagrant-skytap/api/vm"
4
- require "vagrant-skytap/errors"
5
4
 
6
5
  describe VagrantPlugins::Skytap::API::Environment do
7
6
  include_context "unit"
@@ -13,6 +12,7 @@ describe VagrantPlugins::Skytap::API::Environment do
13
12
  let(:network1_attrs) { JSON.load(File.read(File.join(File.expand_path('..', __FILE__), 'skeletons', 'network1.json'))) }
14
13
  let(:vpn_attachment1_attrs) { JSON.load(File.read(File.join(File.expand_path('..', __FILE__), 'skeletons', 'vpn_attachment1.json'))) }
15
14
  let(:empty_environment_attrs) { JSON.load(File.read(File.join(File.expand_path('..', __FILE__), 'skeletons', 'empty_environment.json')))}
15
+ let(:empty_publish_set_attrs) { JSON.load(File.read(File.join(File.expand_path('..', __FILE__), 'skeletons', 'empty_publish_set.json')))}
16
16
 
17
17
  let(:attrs_one_vm) do
18
18
  empty_environment_attrs.dup.tap do |ret|
@@ -26,6 +26,11 @@ describe VagrantPlugins::Skytap::API::Environment do
26
26
  let(:attrs) do
27
27
  attrs_one_vm.dup.tap do |ret|
28
28
  ret['vms'] = [vm1_attrs, vm2_attrs]
29
+ ret['publish_sets'] = [empty_publish_set_attrs.dup]
30
+ ret['publish_sets'].first['vms'] = [
31
+ {"vm_ref" => "http://example.com/vms/#{vm1_attrs['id']}"},
32
+ {"vm_ref" => "http://example.com/vms/#{vm2_attrs['id']}"}
33
+ ]
29
34
  end
30
35
  end
31
36
 
@@ -123,6 +128,13 @@ describe VagrantPlugins::Skytap::API::Environment do
123
128
  it { should be_a VagrantPlugins::Skytap::API::Network }
124
129
  end
125
130
 
131
+ describe "publish_sets" do
132
+ subject do
133
+ instance.publish_sets.first
134
+ end
135
+ it { should be_a VagrantPlugins::Skytap::API::PublishSet }
136
+ end
137
+
126
138
  describe "get_vm_by_id" do
127
139
  subject do
128
140
  instance
@@ -135,9 +147,20 @@ describe VagrantPlugins::Skytap::API::Environment do
135
147
  end
136
148
  end
137
149
 
150
+ describe "get_vms_by_id" do
151
+ subject do
152
+ instance
153
+ end
154
+
155
+ it "should return the appropriate vms from the collection" do
156
+ expect(subject.vms.count).to eq 2
157
+ expect(subject.get_vms_by_id(['6981850', '6981851']).collect(&:name)).to eq ['VM1', 'VM2']
158
+ end
159
+ end
160
+
138
161
  describe "reload" do
139
162
  subject do
140
- old_attrs = attrs_one_vm.merge('networks' => [])
163
+ old_attrs = attrs_one_vm.merge('networks' => [], 'publish_sets' => [])
141
164
  new_attrs = attrs.merge('name' => 'Environment with 2 vms')
142
165
  client = double('api_client',
143
166
  get: double('resp', body: JSON.dump(new_attrs))
@@ -146,14 +169,16 @@ describe VagrantPlugins::Skytap::API::Environment do
146
169
  described_class.new(old_attrs, myenv)
147
170
  end
148
171
 
149
- it "reloads the list of vms and networks" do
172
+ it "reloads the child objects" do
150
173
  expect(subject.name).to eq 'Environment 1'
151
174
  expect(subject.vms.count).to eq 1
152
175
  expect(subject.networks.count).to eq 0
176
+ expect(subject.publish_sets.count).to eq 0
153
177
  subject.reload
154
178
  expect(subject.name).to eq 'Environment with 2 vms'
155
179
  expect(subject.vms.count).to eq 2
156
180
  expect(subject.networks.count).to eq 1
181
+ expect(subject.publish_sets.count).to eq 1
157
182
  end
158
183
  end
159
184