Skip to content

Commit 91e4678

Browse files
sdelanoSeth Falcon
authored andcommitted
specify cookbook versions in environment model
1 parent fbd5460 commit 91e4678

4 files changed

Lines changed: 122 additions & 10 deletions

File tree

chef-server-api/app/controllers/environments.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def update
6767
end
6868

6969
env.description(params["inflated_object"].description)
70+
env.cookbook_versions(params["inflated_object"].cookbook_versions)
7071
env.cdb_save
7172
env.couchdb_rev = nil
7273
self.status = 200

chef/lib/chef/environment.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class Environment
5656
def initialize(couchdb=nil)
5757
@name = ''
5858
@description = ''
59+
@cookbook_versions = Hash.new
5960
@couchdb_rev = nil
6061
@couchdb_id = nil
6162
@couchdb = couchdb || Chef::CouchDB.new
@@ -89,10 +90,24 @@ def description(arg=nil)
8990
)
9091
end
9192

93+
def cookbook_versions(arg=nil)
94+
set_or_return(
95+
:cookbook_versions,
96+
arg,
97+
{
98+
:kind_of => Hash,
99+
:callbacks => {
100+
"should be a valid set of cookbook versions" => lambda { |cv| Chef::Environment.validate_cookbook_versions(cv) }
101+
}
102+
}
103+
)
104+
end
105+
92106
def to_hash
93107
result = {
94108
"name" => @name,
95109
"description" => @description,
110+
"cookbook_versions" => @cookbook_versions,
96111
"json_class" => self.class.name,
97112
"chef_type" => "environment"
98113
}
@@ -108,6 +123,7 @@ def self.json_create(o)
108123
environment = new
109124
environment.name(o["name"])
110125
environment.description(o["description"])
126+
environment.cookbook_versions(o["cookbook_versions"])
111127
environment.couchdb_rev = o["_rev"] if o.has_key?("_rev")
112128
environment.couchdb_id = o["_id"] if o.has_key?("_id")
113129
environment
@@ -180,5 +196,12 @@ def to_s
180196
@name
181197
end
182198

199+
def self.validate_cookbook_versions(cv)
200+
return false unless cv.kind_of?(Hash)
201+
cv.each do |cookbook, version|
202+
return false unless version.kind_of?(String)
203+
end
204+
true
205+
end
183206
end
184207
end

chef/spec/unit/environment_spec.rb

Lines changed: 95 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,70 @@
6868
end
6969
end
7070

71+
describe "cookbook_versions" do
72+
before(:each) do
73+
@cookbook_versions = {
74+
"apt" => "1.0.0",
75+
"god" => "2.0.0",
76+
"apache2" => "4.2.0"
77+
}
78+
end
79+
80+
it "should let you set the cookbook versions in a hash" do
81+
@environment.cookbook_versions(@cookbook_versions).should == @cookbook_versions
82+
end
83+
84+
it "should return the cookbook versions" do
85+
@environment.cookbook_versions(@cookbook_versions)
86+
@environment.cookbook_versions.should == @cookbook_versions
87+
end
88+
89+
it "should not accept anything but a hash" do
90+
lambda { @environment.cookbook_versions("I am a string!") }.should raise_error(ArgumentError)
91+
lambda { @environment.cookbook_versions(Array.new) }.should raise_error(ArgumentError)
92+
lambda { @environment.cookbook_versions(42) }.should raise_error(ArgumentError)
93+
end
94+
95+
it "should validate the hash" do
96+
Chef::Environment.should_receive(:validate_cookbook_versions).with(@cookbook_versions).and_return true
97+
@environment.cookbook_versions(@cookbook_versions)
98+
end
99+
end
100+
101+
describe "to_hash" do
102+
before(:each) do
103+
@environment.name("spec")
104+
@environment.description("Where we run the spec tests")
105+
@environment.cookbook_versions({:apt => "1.2.3"})
106+
@hash = @environment.to_hash
107+
end
108+
109+
%w{name description cookbook_versions}.each do |t|
110+
it "should include '#{t}'" do
111+
@hash[t].should == @environment.send(t.to_sym)
112+
end
113+
end
114+
115+
it "should include 'json_class'" do
116+
@hash["json_class"].should == "Chef::Environment"
117+
end
118+
119+
it "should include 'chef_type'" do
120+
@hash["chef_type"].should == "environment"
121+
end
122+
end
123+
71124
describe "to_json" do
72125
before(:each) do
73126
@environment.name("spec")
74127
@environment.description("Where we run the spec tests")
128+
@environment.cookbook_versions({:apt => "1.2.3"})
75129
@json = @environment.to_json
76130
end
77131

78-
%w{name description}.each do |t|
132+
%w{name description cookbook_versions}.each do |t|
79133
it "should include '#{t}'" do
80-
@json.should =~ /"#{t}":"#{@environment.send(t.to_sym)}"/
134+
@json.should =~ /"#{t}":#{Regexp.escape(@environment.send(t.to_sym).to_json)}/
81135
end
82136
end
83137

@@ -93,10 +147,15 @@
93147
describe "from_json" do
94148
before(:each) do
95149
@data = {
96-
:name => "production",
97-
:description => "We are productive",
98-
:json_class => "Chef::Environment",
99-
:chef_type => "environment"
150+
"name" => "production",
151+
"description" => "We are productive",
152+
"cookbook_versions" => {
153+
"apt" => "1.2.3",
154+
"god" => "4.2.0",
155+
"apache2" => "2.0.0"
156+
},
157+
"json_class" => "Chef::Environment",
158+
"chef_type" => "environment"
100159
}
101160
@environment = JSON.parse(@data.to_json)
102161
end
@@ -105,10 +164,38 @@
105164
@environment.should be_a_kind_of(Chef::Environment)
106165
end
107166

108-
%w{name description}.each do |t|
167+
%w{name description cookbook_versions}.each do |t|
109168
it "should match '#{t}'" do
110-
@environment.send(t.to_sym).should == @data[t.to_sym]
169+
@environment.send(t.to_sym).should == @data[t]
111170
end
112171
end
113172
end
173+
174+
describe "self.validate_cookbook_versions" do
175+
before(:each) do
176+
@cookbook_versions = {
177+
"apt" => "1.0.0",
178+
"god" => "2.0.0",
179+
"apache2" => "4.2.0"
180+
}
181+
end
182+
183+
it "should return true when all versions are strings" do
184+
Chef::Environment.validate_cookbook_versions(@cookbook_versions).should == true
185+
end
186+
187+
it "should return false when anything other than a string is passed as a version" do
188+
a = @cookbook_versions.dup.merge :number => 2
189+
Chef::Environment.validate_cookbook_versions(a).should == false
190+
191+
b = @cookbook_versions.dup.merge :hash => {:foo => 'bar'}
192+
Chef::Environment.validate_cookbook_versions(b).should == false
193+
194+
c = @cookbook_versions.dup.merge :array => ['this', 'is', 'a', 'bad', 'version']
195+
Chef::Environment.validate_cookbook_versions(c).should == false
196+
197+
d = @cookbook_versions.dup.merge :cookbook_versions => Chef::CookbookVersion.new("meta")
198+
Chef::Environment.validate_cookbook_versions(d).should == false
199+
end
200+
end
114201
end

features/api/environments/update_environment_api.feature

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ Feature: Update an environment via the REST API
1414
Then the inflated response should respond to '<method>' with '<updated_value>'
1515

1616
Examples:
17-
| method | updated_value |
18-
| description | I am a pickle |
17+
| method | updated_value |
18+
| description | I am a pickle |
19+
| cookbook_versions | {"apt": "1.2.3"} |
1920

2021
Scenario: Update an environment that does not exist
2122
Given I am an administrator

0 commit comments

Comments
 (0)