cobbler 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ require 'pathname'
2
+ dir = Pathname.new(__FILE__).parent
3
+ $LOAD_PATH.unshift(File.join(dir,'lib'))
4
+ require 'cobbler'
5
+ gem 'rspec', '~> 2.5.0'
6
+ require 'mocha'
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :mocha
10
+ end
11
+
12
+ def with_real_cobbler(calzz,&blk)
13
+ unless ENV['NO_REAL_COBBLER'] == '1'
14
+ config = (ENV['COBBLER_YML'] || File.expand_path(File.join(File.dirname(__FILE__),'..','config','cobbler.yml')))
15
+ if File.exist?(config) && (yml = YAML::load(File.open(config))) && (yml['hostname'] && yml['username'] && yml['password'])
16
+ yield(yml)
17
+ else
18
+ puts "No cobbler data found."
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,194 @@
1
+ #! /usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../spec_helper'
3
+
4
+ class BaseTest < Cobbler::Base
5
+ cobbler_field :name
6
+ cobbler_field :locked_field, :locked => true
7
+ cobbler_field :saveable_field
8
+ end
9
+
10
+ class Unremovable < Cobbler::Base
11
+ cobbler_lifecycle :remove => false
12
+ end
13
+
14
+ class Unsaveable1 < Cobbler::Base
15
+ cobbler_lifecycle :handle => false
16
+ end
17
+
18
+ class Unsaveable2 < Cobbler::Base
19
+ cobbler_lifecycle :modify => false
20
+ end
21
+
22
+ class Unsaveable3 < Cobbler::Base
23
+ cobbler_lifecycle :new => false, :save => false
24
+ end
25
+
26
+ class CollTest1 < Cobbler::Base
27
+ cobbler_field :name
28
+ cobbler_collection :coll1
29
+ end
30
+ class CollTest2 < Cobbler::Base
31
+ cobbler_field :name
32
+ cobbler_collection :coll2, :store => :store_coll2
33
+
34
+ def store_coll2
35
+ coll2.to_a.each do |item|
36
+ #do something
37
+ end
38
+ end
39
+ end
40
+
41
+ describe Cobbler::Base do
42
+
43
+ [:remove, :save ].each do |method|
44
+ it "should provide a method to #{method} the item" do
45
+ test = BaseTest.new
46
+ test.should respond_to(method)
47
+ end
48
+ end
49
+
50
+ describe "when initializing" do
51
+ it "should add the fields to the user fields" do
52
+ test = BaseTest.new({'name' => 1, 'b' => 2})
53
+ test.definitions.keys.should be_empty
54
+ test.user_definitions.keys.should_not be_empty
55
+ test.user_definitions.keys.should include('name')
56
+ test.user_definitions.keys.should include('b')
57
+ test.name.should == 1
58
+ end
59
+
60
+ it "should add the fields to the old definitions if it's an old record" do
61
+ test = BaseTest.new({:a => 1, :b => 2},false)
62
+ test.definitions.keys.should_not be_empty
63
+ test.definitions.keys.should include(:a)
64
+ test.definitions.keys.should include(:b)
65
+ test.user_definitions.keys.should be_empty
66
+ end
67
+ end
68
+
69
+ describe "when removing an item" do
70
+ it "should raise an exception if we have no api_method to remove the item" do
71
+ lambda { Unremovable.new.remove }.should raise_error(Exception)
72
+ end
73
+
74
+ it "should call the remove api_method for the item" do
75
+ test = BaseTest.new({'name' => 'foo'})
76
+ test.name.should == 'foo'
77
+ connection = Object.new
78
+ BaseTest.expects(:login).returns('muh')
79
+ BaseTest.expects(:logout)
80
+ BaseTest.expects(:connect).returns(connection)
81
+ BaseTest.expects(:make_call).with(test.api_methods[:remove],test.name,'muh')
82
+ test.remove
83
+ end
84
+ end
85
+
86
+ describe "when trying to save an item" do
87
+ it "should raise an exception if we have no api_method to save and/or update the item" do
88
+ [Unsaveable1,Unsaveable2,Unsaveable3].each do |klass|
89
+ lambda { klass.new.save }.should raise_error(Exception)
90
+ end
91
+ end
92
+ end
93
+ describe "when saving an existing item" do
94
+ before(:each) do
95
+ @test1 = BaseTest.new({'name' => 'foo','locked_field' => '1', 'saveable_field' => 2},false)
96
+ BaseTest.expects(:connect).returns(Object.new)
97
+ BaseTest.expects(:login).returns('muh')
98
+ BaseTest.expects(:logout)
99
+ BaseTest.expects(:find_one).with('foo').returns('entry')
100
+ BaseTest.expects(:make_call).with('get_base_test_handle','foo','muh').returns('id')
101
+ BaseTest.expects(:make_call).with('save_base_test','id','muh')
102
+ end
103
+ it "should store no fields on a unchanged record" do
104
+ [:name,:locked_field,:saveable_field].each do |field|
105
+ BaseTest.expects(:make_call).with('modify_base_test','id',"#{field}",@test1.send(field),'muh').never
106
+ end
107
+ @test1.save
108
+ end
109
+
110
+ it "should only store changed fields" do
111
+ @test1.saveable_field = 3
112
+ [:name,:locked_field].each do |field|
113
+ BaseTest.expects(:make_call).with('modify_base_test','id',"#{field}",@test1.send(field),'muh').never
114
+ end
115
+ BaseTest.expects(:make_call).with('modify_base_test','id',"saveable_field",3,'muh')
116
+ @test1.save
117
+ end
118
+
119
+ it "should store no locked fields" do
120
+ @test1.locked_field = 'foobar'
121
+ [:name,:locked_field,:saveable_field].each do |field|
122
+ BaseTest.expects(:make_call).with('modify_base_test','id',"#{field}",@test1.send(field),'muh').never
123
+ end
124
+ @test1.save
125
+ end
126
+ end
127
+
128
+ describe "when saving a not yet existing item" do
129
+ before(:each) do
130
+ @test1 = BaseTest.new({'name' => 'foo','locked_field' => '1', 'saveable_field' => 2},false)
131
+ BaseTest.expects(:connect).returns(Object.new)
132
+ BaseTest.expects(:find_one).with('foo').returns(nil)
133
+ BaseTest.expects(:login).returns('muh')
134
+ BaseTest.expects(:logout)
135
+ BaseTest.expects(:make_call).with('new_base_test','muh').returns('id')
136
+ BaseTest.expects(:make_call).with('modify_base_test','id',"name",@test1.name,'muh')
137
+ BaseTest.expects(:make_call).with('save_base_test','id','muh')
138
+ end
139
+ it "should store no fields on a unchanged record" do
140
+ [:name,:locked_field,:saveable_field].each do |field|
141
+ BaseTest.expects(:make_call).with('modify_base_test','id',"#{field}",@test1.send(field),'muh').never
142
+ end
143
+ @test1.save
144
+ end
145
+
146
+ it "should only store changed fields" do
147
+ @test1.saveable_field = 3
148
+ [:name,:locked_field].each do |field|
149
+ BaseTest.expects(:make_call).with('modify_base_test','id',"#{field}",@test1.send(field),'muh').never
150
+ end
151
+ BaseTest.expects(:make_call).with('modify_base_test','id',"saveable_field",3,'muh')
152
+ @test1.save
153
+ end
154
+
155
+ it "should store no locked fields" do
156
+ @test1.locked_field = 'foobar'
157
+ [:name,:locked_field,:saveable_field].each do |field|
158
+ BaseTest.expects(:make_call).with('modify_base_test','id',"#{field}",@test1.send(field),'muh').never
159
+ end
160
+ @test1.save
161
+ end
162
+ end
163
+
164
+ describe "when saving an item with collections" do
165
+ it "should store a normal collection as a normal field" do
166
+ @test1 = CollTest1.new({'name' => 'foo'},false)
167
+ @test1.coll1 = [1,2]
168
+ CollTest1.expects(:connect).returns(Object.new)
169
+ CollTest1.expects(:find_one).with('foo').returns(nil)
170
+ CollTest1.expects(:login).returns('muh')
171
+ CollTest1.expects(:logout)
172
+ CollTest1.expects(:make_call).with('new_coll_test1','muh').returns('id')
173
+ CollTest1.expects(:make_call).with('modify_coll_test1','id',"name",@test1.name,'muh')
174
+ CollTest1.expects(:make_call).with('modify_coll_test1','id',"coll1",[1,2],'muh')
175
+ CollTest1.expects(:make_call).with('save_coll_test1','id','muh')
176
+ @test1.save
177
+ end
178
+
179
+ it "should call the store methods for a special storeable field" do
180
+ @test1 = CollTest2.new({'name' => 'foo'},false)
181
+ @test1.coll2 = [1,2]
182
+ CollTest2.expects(:connect).returns(Object.new)
183
+ CollTest2.expects(:find_one).with('foo').returns(nil)
184
+ CollTest2.expects(:login).returns('muh')
185
+ CollTest2.expects(:logout)
186
+ CollTest2.expects(:make_call).with('new_coll_test2','muh').returns('id')
187
+ CollTest2.expects(:make_call).with('modify_coll_test2','id',"name",@test1.name,'muh')
188
+ @test1.expects(:store_coll2)
189
+ CollTest2.expects(:make_call).with('save_coll_test2','id','muh')
190
+ @test1.save
191
+ end
192
+ end
193
+
194
+ end
@@ -0,0 +1,44 @@
1
+ #! /usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../../spec_helper'
3
+
4
+ class TestDebug
5
+ include Cobbler::Common::Debug
6
+ end
7
+
8
+ describe Cobbler::Common::Debug do
9
+
10
+ it "should provide a way to set and query a debug flag" do
11
+ TestDebug.should respond_to(:debug_enabled)
12
+ TestDebug.should respond_to(:debug_enabled=)
13
+ end
14
+
15
+ it "should provide a way to set and query an output engine" do
16
+ TestDebug.should respond_to(:output)
17
+ TestDebug.should respond_to(:output=)
18
+ end
19
+
20
+ it "should provide a method to print debug messages on class and instance level" do
21
+ TestDebug.should respond_to(:debug)
22
+ TestDebug.new.should respond_to(:debug)
23
+ end
24
+
25
+ it "should not have debugging enabled by default" do
26
+ TestDebug.debug_enabled.should == false
27
+ end
28
+
29
+ it "should not print out a debug message if the debug flag is not set" do
30
+ output = Object.new
31
+ output.expects(:puts).with('foo').never
32
+ TestDebug.output = output
33
+ TestDebug.debug('foo')
34
+ end
35
+
36
+ it "should print out a debug message if the debug flag is set" do
37
+ TestDebug.debug_enabled = true
38
+ output = Object.new
39
+ output.expects(:puts).with('foo').once
40
+ TestDebug.output = output
41
+ TestDebug.debug('foo')
42
+ end
43
+
44
+ end
@@ -0,0 +1,101 @@
1
+ #! /usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../../spec_helper'
3
+
4
+ class TestFinder
5
+
6
+ def initialize(a,b)
7
+
8
+ end
9
+
10
+ include Cobbler::Common::Debug
11
+ include Cobbler::Connection::Handling
12
+ include Cobbler::Common::Lifecycle
13
+ include Cobbler::Common::Finders
14
+ end
15
+
16
+ describe Cobbler::Common::Finders do
17
+ it "should provide a way to find all" do
18
+ TestFinder.should respond_to(:find)
19
+ end
20
+ it "should provide a way to find one" do
21
+ TestFinder.should respond_to(:find_one)
22
+ end
23
+
24
+ describe "lookup" do
25
+ it "should raise an exception if we don't know how to lookup all" do
26
+ api_methods = Object.new
27
+ api_methods.stubs(:[]).with(:find_all).returns(nil)
28
+ TestFinder.stubs(:api_methods).returns(api_methods)
29
+ lambda{ TestFinder.find_all }.should raise_error(Exception)
30
+ end
31
+
32
+ it "should raise an exception if we don't know how to lookup an item" do
33
+ api_methods = Object.new
34
+ api_methods.stubs(:[]).with(:find_one).returns(nil)
35
+ TestFinder.stubs(:api_methods).returns(api_methods)
36
+ lambda{ TestFinder.find_one('foo') }.should raise_error(Exception)
37
+ end
38
+
39
+ it "should use the :find_one api_method to lookup an item" do
40
+ TestFinder.api_methods[:find_one] = 'find_one'
41
+ connection = Object.new
42
+ TestFinder.expects(:connect).returns(connection)
43
+ TestFinder.stubs(:make_call).with('find_one','foo').returns({})
44
+ item = TestFinder.find_one('foo')
45
+ item.should be_nil
46
+ end
47
+
48
+ it "should return nil if api returns '~'" do
49
+ TestFinder.api_methods[:find_one] = 'find_one'
50
+ connection = Object.new
51
+ TestFinder.expects(:connect).returns(connection)
52
+ TestFinder.stubs(:make_call).with('find_one','foo').returns('~')
53
+ item = TestFinder.find_one('foo')
54
+ item.should be_nil
55
+ end
56
+
57
+ describe "is unsuccessful" do
58
+ it "should return an empty array if nothing is found" do
59
+ TestFinder.stubs(:in_transaction).returns([])
60
+ TestFinder.find.should be_empty
61
+ end
62
+ it "should return nil if nothing is found" do
63
+ TestFinder.stubs(:in_transaction).returns({})
64
+ TestFinder.find_one('foo').should be_nil
65
+ end
66
+ end
67
+
68
+ describe "successfully all items" do
69
+ before(:each) do
70
+ TestFinder.stubs(:in_transaction).returns([1,2])
71
+ end
72
+ it "should return an array of Objects of itself if something is found" do
73
+ items = TestFinder.find
74
+ items.should have(2).items
75
+ items.first.should be_a(TestFinder)
76
+ items.last.should be_a(TestFinder)
77
+ end
78
+
79
+ it "should pass each found item to the passed block but return the found items" do
80
+ items = TestFinder.find do |item|
81
+ item.should be_a(TestFinder)
82
+ end
83
+ items.should have(2).items
84
+ items.first.should be_a(TestFinder)
85
+ items.last.should be_a(TestFinder)
86
+ end
87
+ end
88
+
89
+ describe "successfully one item" do
90
+ it "should return an item" do
91
+ TestFinder.stubs(:in_transaction).returns({:a => 1})
92
+ TestFinder.find_one('foo').should be_a(TestFinder)
93
+ end
94
+
95
+ it "should return nil if nothing is found" do
96
+ TestFinder.stubs(:in_transaction).returns({})
97
+ TestFinder.find_one('foo').should be_nil
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,192 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ class TestLifecycle
4
+
5
+ def initialize(a=nil,b=nil)
6
+ @definitions = Hash.new(a)
7
+ end
8
+
9
+ include Cobbler::Common::Debug
10
+ include Cobbler::Connection::Handling
11
+ include Cobbler::Common::Lifecycle
12
+
13
+ cobbler_field :name
14
+ cobbler_field :foo, :locked => true
15
+ cobbler_field :findme, :findable => 'find_me'
16
+ cobbler_field :super_field, :locked => true, :findable => 'find_super'
17
+
18
+ cobbler_fields :foo1, :foo2
19
+
20
+ cobbler_collection :coll1
21
+ cobbler_collection :coll2, :packing => Hash
22
+ cobbler_collection :coll3, :store => :foobar
23
+ end
24
+
25
+ class TestLifecycle2
26
+ def initialize(a,b); end
27
+ include Cobbler::Common::Debug
28
+ include Cobbler::Connection::Handling
29
+ include Cobbler::Common::Lifecycle
30
+ cobbler_field :name, :locked => false, :findable => false
31
+ cobbler_lifecycle :find_all => 'foobar', :find_one => false
32
+ end
33
+
34
+ describe Cobbler::Common::Lifecycle do
35
+
36
+ it "should provide a bunch of api_methods for that object" do
37
+ TestLifecycle.api_methods.keys.should_not be_empty
38
+ end
39
+
40
+ [ :find_all, :find_one, :handle, :remove, :save, :new, :modify].each do |method|
41
+ it "should provide an api_method for #{method} and be derived from the classname" do
42
+ TestLifecycle.api_methods[method].should_not be_nil
43
+ TestLifecycle.api_methods[method].should =~ /test_lifecycle/
44
+ end
45
+ end
46
+
47
+ describe "defining lifecycle" do
48
+ it "should provide a way to define a lifecycle" do
49
+ TestLifecycle.should respond_to(:cobbler_lifecycle)
50
+ end
51
+
52
+ it "should set the api_method according to the one we defined" do
53
+ TestLifecycle2.api_methods[:find_all].should == 'foobar'
54
+ TestLifecycle2.api_methods[:find_one].should be_false
55
+ end
56
+
57
+ [ :handle, :remove, :save, :new, :modify].each do |method|
58
+ it "should define method #{method}" do
59
+ TestLifecycle2.api_methods[method].should_not be_nil
60
+ TestLifecycle2.api_methods[method].should =~ /test_lifecycle/
61
+ end
62
+
63
+ end
64
+ end
65
+
66
+ describe "define a cobbler field" do
67
+ it "should provide a way to define a cobbler field" do
68
+ TestLifecycle.should respond_to(:cobbler_field)
69
+ end
70
+
71
+ it "should provide a way to define multiple cobbler fields" do
72
+ TestLifecycle.should respond_to(:cobbler_fields)
73
+ end
74
+
75
+ it "should add this field to the record fields" do
76
+ TestLifecycle.cobbler_record_fields.should include(:name)
77
+ end
78
+
79
+ it "should add the name field as findable" do
80
+ TestLifecycle.should respond_to(:find_by_name)
81
+ end
82
+
83
+ it "should lock the name field" do
84
+ TestLifecycle.locked_fields.should include(:name)
85
+ end
86
+
87
+ it "should not add the name field as findable if we mark it" do
88
+ TestLifecycle2.should_not respond_to(:find_by_name)
89
+ end
90
+
91
+ it "should lock the name field" do
92
+ TestLifecycle2.locked_fields.should_not include(:name)
93
+ end
94
+
95
+ it "should be available as getter and setter on an instance" do
96
+ test = TestLifecycle.new
97
+ test.should respond_to(:name)
98
+ test.should respond_to(:name=)
99
+ end
100
+
101
+ it "should handle cobbler_fields over to cobbler_field" do
102
+ test = TestLifecycle.new
103
+ [:foo1,:foo2].each do |field|
104
+ test.should respond_to(field)
105
+ test.should respond_to(:"#{field}=")
106
+ TestLifecycle.cobbler_record_fields.should include(field)
107
+ end
108
+ end
109
+
110
+ it "should be possible to mark that field as locked" do
111
+ TestLifecycle.locked_fields.should include(:foo)
112
+ TestLifecycle.locked_fields.should include(:super_field)
113
+ end
114
+
115
+ it "should be possible to mark a field as findable" do
116
+ TestLifecycle.should respond_to(:find_by_findme)
117
+ TestLifecycle.should respond_to(:find_by_super_field)
118
+ end
119
+
120
+ describe "which is findable" do
121
+ before(:each) do
122
+ connection = Object.new
123
+ TestLifecycle.expects(:connect).returns(connection)
124
+ end
125
+
126
+ it "should lookup that field" do
127
+ TestLifecycle.expects(:make_call).with('get_test_lifecycle','foo').returns('a')
128
+ item = TestLifecycle.find_by_name('foo')
129
+ item.should be_a(TestLifecycle)
130
+ end
131
+ it "should lookup the field with the appropriate api method" do
132
+ TestLifecycle.expects(:make_call).with('find_super','foo').returns('a')
133
+ item = TestLifecycle.find_by_super_field('foo')
134
+ item.should be_a(TestLifecycle)
135
+ end
136
+
137
+ it "should return nil if nothing is found" do
138
+ TestLifecycle.expects(:make_call).with('get_test_lifecycle','foo').returns(nil)
139
+ TestLifecycle.find_by_name('foo').should be_nil
140
+ end
141
+ end
142
+ end
143
+ describe "define a cobbler collection" do
144
+ it "should provide a way to define a cobbler collection" do
145
+ TestLifecycle.should respond_to(:cobbler_collection)
146
+ end
147
+
148
+ it "should provide accessor and setter for a collection" do
149
+ TestLifecycle.new.should respond_to(:coll1)
150
+ TestLifecycle.new.should respond_to(:coll1=)
151
+ end
152
+
153
+ it "should add the collection to the fields" do
154
+ TestLifecycle.cobbler_record_fields.should include(:coll1)
155
+ TestLifecycle.cobbler_record_fields.should include(:coll2)
156
+ end
157
+
158
+ it "should set a default type to be an array" do
159
+ TestLifecycle.new.coll1.should be_a(Array)
160
+ end
161
+
162
+ it "should be possible to set packing as Hash" do
163
+ TestLifecycle.new.coll2.should be_a(Hash)
164
+ end
165
+
166
+ it "should be possible to define a special store callback" do
167
+ TestLifecycle.cobbler_record_fields.should_not include(:coll3)
168
+ TestLifecycle.cobbler_collections_store_callbacks.should include(:foobar)
169
+ end
170
+ end
171
+
172
+ describe "assigning new values" do
173
+ it "should not be added to the original definitions" do
174
+ test = TestLifecycle.new
175
+ test.name = 'foo'
176
+ test.name.should == 'foo'
177
+ test.definitions['name'].should_not == 'foo'
178
+ test.user_definitions['name'].should == 'foo'
179
+ end
180
+
181
+ it "should always be added to the user_definitions if it as collection" do
182
+ test = TestLifecycle.new
183
+ test.coll1.should == []
184
+ test.coll1 = [1,2]
185
+ test.coll1.should == [1,2]
186
+ test.user_definitions['coll1'].should == [1,2]
187
+ test.coll1 << 3
188
+ test.coll1 == [1,2,3]
189
+ end
190
+ end
191
+
192
+ end
@@ -0,0 +1,59 @@
1
+ #! /usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../../spec_helper'
3
+
4
+ class TestConnection
5
+ include Cobbler::Common::Debug
6
+ include Cobbler::Connection::Handling
7
+ include Cobbler::Connection::Common
8
+ end
9
+
10
+ describe Cobbler::Connection::Common do
11
+ it "should provide a method to test a connection" do
12
+ TestConnection.should respond_to(:test_connection)
13
+ end
14
+
15
+ it "should provide a method to start a sync" do
16
+ TestConnection.should respond_to(:sync)
17
+ end
18
+
19
+ describe "testing a connection" do
20
+
21
+ before(:each) do
22
+ connection = Object.new
23
+ TestConnection.expects(:connect).returns(connection)
24
+ end
25
+
26
+ it "should return false if login fails" do
27
+ TestConnection.expects(:login).returns(nil)
28
+ TestConnection.test_connection.should be_false
29
+ end
30
+ it "should return true if login succeeds and logout" do
31
+ TestConnection.expects(:login).returns("true")
32
+ TestConnection.expects(:logout)
33
+ TestConnection.test_connection.should be_true
34
+ end
35
+ end
36
+
37
+ with_real_cobbler(TestConnection) do |cobbler_yml|
38
+ describe "testing a real connection" do
39
+ before(:each) do
40
+ TestConnection.hostname = yml['hostname']
41
+ TestConnection.username = yml['username']
42
+ TestConnection.password = yml['password']
43
+ end
44
+
45
+ it "should "
46
+ end
47
+ end
48
+
49
+ describe "syncing a cobbler" do
50
+ it "should send the sync command" do
51
+ connection =
52
+ TestConnection.expects(:connect).returns(Object.new)
53
+ TestConnection.expects(:login).returns('foobar')
54
+ TestConnection.expects(:logout)
55
+ TestConnection.expects(:make_call).with('sync','foobar')
56
+ TestConnection.sync
57
+ end
58
+ end
59
+ end