jenkins-plugin-runtime 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +2 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +21 -0
  5. data/jenkins-plugin-runtime.gemspec +30 -0
  6. data/lib/jenkins/launcher.rb +15 -0
  7. data/lib/jenkins/model.rb +91 -0
  8. data/lib/jenkins/model/action.rb +37 -0
  9. data/lib/jenkins/model/build.rb +21 -0
  10. data/lib/jenkins/model/describable.rb +75 -0
  11. data/lib/jenkins/model/descriptor.rb +40 -0
  12. data/lib/jenkins/model/listener.rb +47 -0
  13. data/lib/jenkins/plugin.rb +141 -0
  14. data/lib/jenkins/plugin/cli.rb +20 -0
  15. data/lib/jenkins/plugin/proxies.rb +131 -0
  16. data/lib/jenkins/plugin/proxies/build_wrapper.rb +50 -0
  17. data/lib/jenkins/plugin/proxies/builder.rb +22 -0
  18. data/lib/jenkins/plugin/proxy.rb +76 -0
  19. data/lib/jenkins/plugin/runtime.rb +13 -0
  20. data/lib/jenkins/plugin/runtime/version.rb +7 -0
  21. data/lib/jenkins/slaves/cloud.rb +9 -0
  22. data/lib/jenkins/tasks/build_wrapper.rb +39 -0
  23. data/lib/jenkins/tasks/builder.rb +33 -0
  24. data/spec/jenkins/launcher_spec.rb +8 -0
  25. data/spec/jenkins/model/action_spec.rb +36 -0
  26. data/spec/jenkins/model/build_spec.rb +8 -0
  27. data/spec/jenkins/model/describable_spec.rb +51 -0
  28. data/spec/jenkins/model/listener_spec.rb +31 -0
  29. data/spec/jenkins/model_spec.rb +100 -0
  30. data/spec/jenkins/plugin/proxies/build_wrapper_spec.rb +25 -0
  31. data/spec/jenkins/plugin/proxies/builder_spec.rb +24 -0
  32. data/spec/jenkins/plugin/proxies/proxy_helper.rb +24 -0
  33. data/spec/jenkins/plugin/proxies_spec.rb +148 -0
  34. data/spec/jenkins/plugin/proxy_spec.rb +43 -0
  35. data/spec/jenkins/plugin_spec.rb +7 -0
  36. data/spec/jenkins/tasks/build_wrapper_spec.rb +7 -0
  37. data/spec/jenkins/tasks/builder_spec.rb +8 -0
  38. data/spec/spec_helper.rb +11 -0
  39. data/src/jenkins/ruby/DoDynamic.java +18 -0
  40. data/src/jenkins/ruby/Get.java +18 -0
  41. metadata +175 -0
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jenkins::Model::Build do
4
+
5
+ it "can be instantiated" do
6
+ Jenkins::Model::Build.new(mock(Java.hudson.model.AbstractBuild))
7
+ end
8
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'rspec-spies'
3
+ describe Jenkins::Model::Describable do
4
+
5
+ before do
6
+ @plugin = mock(Jenkins::Plugin)
7
+ Jenkins::Plugin.stub(:instance).and_return(@plugin)
8
+ end
9
+
10
+ describe "when mixed into a class" do
11
+ before do
12
+ @class = Class.new
13
+ @class.send(:include, Jenkins::Model::Describable)
14
+ @plugin.stub(:register_describable)
15
+ end
16
+
17
+
18
+ it "can't be described as plain old object" do
19
+ lambda {@class.describe_as Object}.should raise_error(Jenkins::Model::Describable::DescribableError)
20
+ end
21
+
22
+ it "can't be described as plain old java object" do
23
+ lambda {@class.describe_as java.lang.Object.new}.should raise_error(Jenkins::Model::Describable::DescribableError)
24
+ end
25
+
26
+ it "must be described as a java.lang.Class" do
27
+ lambda {@class.describe_as java.lang.Object}.should_not raise_error
28
+ end
29
+
30
+ describe "a subclass of that class" do
31
+ before do
32
+ @class.describe_as java.lang.Object
33
+ @subclass = Class.new(@class)
34
+ end
35
+
36
+ it "is registered as an extension of the java type" do
37
+ @plugin.should have_received(:register_describable).with(@subclass, java.lang.Object.java_class)
38
+ end
39
+
40
+ describe ". a sub-subclass" do
41
+ before do
42
+ @subsubclass = Class.new(@subclass)
43
+ end
44
+
45
+ it "is also registered as an extension of the original java type" do
46
+ @plugin.should have_received(:register_describable).with(@subsubclass, java.lang.Object.java_class)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jenkins::Model::Listener do
4
+
5
+ before do
6
+ @output = java.io.ByteArrayOutputStream.new
7
+ @java = Java.hudson.util.StreamTaskListener.new(@output)
8
+ @listener = Jenkins::Model::Listener.new(@java)
9
+ end
10
+
11
+ it "logs messages" do
12
+ @listener.log('Hi')
13
+ @output.toString.should eql "Hi"
14
+ end
15
+
16
+ it "logs errors" do
17
+ @listener.error('Oh no!')
18
+ @output.toString.should match /^ERROR: Oh no!/
19
+ end
20
+
21
+ it "logs fatal errors" do
22
+ @listener.fatal('boom!')
23
+ @output.toString.should match /^FATAL: boom!/
24
+ end
25
+
26
+ it "logs hyperlinks" do
27
+ @java.should_receive(:hyperlink).with("/foo/bar", "click here")
28
+ @listener.hyperlink("/foo/bar", "click here")
29
+ end
30
+ end
31
+
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jenkins::Model do
4
+ Model = Jenkins::Model
5
+
6
+ it "has a display name which is settable via the class, and accessable via the class and instance" do
7
+ cls = new_model do
8
+ display_name "One-Off Class"
9
+ end
10
+ cls.display_name.should eql "One-Off Class"
11
+ cls.new.display_name.should eql "One-Off Class"
12
+ end
13
+
14
+ it "passes down display_name capabilities to subclasses" do
15
+ parent = new_model
16
+ child = Class.new(parent)
17
+ child.class_eval do
18
+ display_name "Child"
19
+ end
20
+ child.display_name.should eql "Child"
21
+ end
22
+
23
+ it "passes down display_name capabilities to submodules" do
24
+ submodule = Module.new
25
+ submodule.send(:include, Jenkins::Model)
26
+ cls = Class.new
27
+ cls.send(:include, submodule)
28
+ cls.display_name "SubAwesome"
29
+ cls.display_name.should eql "SubAwesome"
30
+ cls.new.display_name.should eql "SubAwesome"
31
+ end
32
+
33
+ it "has a default display name of the class name" do
34
+ cls = new_model do
35
+ def self.name
36
+ "AwesomeClass"
37
+ end
38
+ end
39
+ cls.display_name.should eql "AwesomeClass"
40
+ end
41
+
42
+ it "keeps a list of which of its properties are transient" do
43
+ cls = new_model do
44
+ transient :foo, :bar
45
+ end
46
+ cls.should be_transient(:foo)
47
+ cls.should be_transient(:bar)
48
+ cls.should_not be_transient(:baz)
49
+ end
50
+
51
+ it "includes parent classes's transient properties, but doesn't affect the parent property list" do
52
+ parent = new_model do
53
+ transient :foo
54
+ end
55
+ child = Class.new(parent)
56
+ child.class_eval do
57
+ transient :bar
58
+ end
59
+ parent.should_not be_transient(:bar)
60
+ child.should be_transient(:foo)
61
+ child.should be_transient(:bar)
62
+ end
63
+
64
+ describe "tracking descendants" do
65
+ before do
66
+ Model.clear
67
+ end
68
+
69
+ it "captures including classes" do
70
+ cls = Class.new
71
+ cls.send(:include, Model)
72
+ Model.should be_descendant cls
73
+ end
74
+
75
+ it "captures classes that extend including classes" do
76
+ cls = Class.new
77
+ cls.send(:include, Model)
78
+ Model.should be_descendant(Class.new(cls))
79
+ end
80
+
81
+ it "captures classes that include including modules" do
82
+ m1 = Module.new
83
+ m1.send(:include, Model)
84
+ m2 = Module.new
85
+ m2.send(:include, m1)
86
+ cls = Class.new
87
+ cls.send(:include, m2)
88
+ Model.should be_descendant(Class.new(cls))
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def new_model(&block)
95
+ cls = Class.new
96
+ cls.send(:include, Jenkins::Model)
97
+ cls.class_eval(&block) if block_given?
98
+ return cls
99
+ end
100
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe Jenkins::Plugin::Proxies::BuildWrapper do
5
+ include ProxyHelper
6
+
7
+ subject {Jenkins::Plugin::Proxies::BuildWrapper}
8
+ it {should be_transient(:plugin)}
9
+
10
+ before do
11
+ @object = mock(Jenkins::Tasks::BuildWrapper)
12
+ @wrapper = Jenkins::Plugin::Proxies::BuildWrapper.new(@plugin, @object)
13
+ end
14
+
15
+ it "passes in an env file which will be called to " do
16
+ env = nil
17
+ @object.should_receive(:setup).with(@build, @launcher, @listener, an_instance_of(Hash)) do |*args|
18
+ env = args.last
19
+ end
20
+ environment = @wrapper.setUp(@jBuild, @jLauncher, @jListener)
21
+
22
+ @object.should_receive(:teardown).with(@build, @listener, env)
23
+ environment.tearDown(@jBuild, @jListener)
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jenkins::Plugin::Proxies::Builder do
4
+ include ProxyHelper
5
+
6
+ before do
7
+ @object = mock(Jenkins::Tasks::Builder)
8
+ @builder = Jenkins::Plugin::Proxies::Builder.new(@plugin, @object)
9
+ end
10
+
11
+ describe "prebuild" do
12
+ it "calls through to its implementation" do
13
+ @object.should_receive(:prebuild).with(@build, @launcher, @listener)
14
+ @builder.prebuild(@jBuild, @jLauncher, @jListener)
15
+ end
16
+ end
17
+
18
+ describe "perform" do
19
+ it "calls through to its implementation" do
20
+ @object.should_receive(:perform).with(@build, @launcher, @listener)
21
+ @builder.perform(@jBuild, @jLauncher, @jListener)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+
2
+ module ProxyHelper
3
+
4
+ def self.included(mod)
5
+ super
6
+ mod.class_eval do
7
+ before do
8
+ @plugin = mock(Jenkins::Plugin, :name => "test-plugin")
9
+
10
+ @jBuild = mock(Java.hudson.model.AbstractBuild)
11
+ @jLauncher = mock(Java.hudson.Launcher)
12
+ @jListener = mock(Java.hudson.model.BuildListener)
13
+
14
+ @build = mock(Jenkins::Model::Build)
15
+ @launcher = mock(Jenkins::Launcher)
16
+ @listener = mock(Jenkins::Model::Listener)
17
+
18
+ @plugin.stub(:import).with(@jBuild).and_return(@build)
19
+ @plugin.stub(:import).with(@jLauncher).and_return(@launcher)
20
+ @plugin.stub(:import).with(@jListener).and_return(@listener)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jenkins::Plugin::Proxies do
4
+ Proxies = Jenkins::Plugin::Proxies
5
+ before do
6
+ Proxies.clear
7
+ @plugin = mock(Jenkins::Plugin)
8
+ @proxies = Jenkins::Plugin::Proxies.new(@plugin)
9
+ end
10
+
11
+ describe "exporting a native ruby object" do
12
+
13
+ before do
14
+ @class = Class.new
15
+ @object = @class.new
16
+ end
17
+
18
+ describe "when no wrapper exists for it" do
19
+
20
+ describe "and there is a matching proxy class registered" do
21
+ before do
22
+ @proxy_class = Class.new
23
+ @proxy_class.class_eval do
24
+ attr_reader :plugin, :object
25
+ def initialize(plugin, object)
26
+ @plugin, @object = plugin, object
27
+ end
28
+ end
29
+ Jenkins::Plugin::Proxies.register @class, @proxy_class
30
+ @export = @proxies.export(@object)
31
+ end
32
+
33
+ it "instantiates the proxy" do
34
+ @export.should be_kind_of(@proxy_class)
35
+ end
36
+
37
+ it "passes in the plugin and the wrapped object" do
38
+ @export.plugin.should be(@plugin)
39
+ @export.object.should be(@object)
40
+ end
41
+ end
42
+
43
+ describe "and there is not an appropriate proxy class registered for it" do
44
+ it "raises an exception on import" do
45
+ expect {@proxies.export(@object)}.should raise_error
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "when a wrapper has already existed" do
51
+ before do
52
+ @proxy = Object.new
53
+ @proxies.link @object, @proxy
54
+ end
55
+
56
+ it "finds the same proxy on export" do
57
+ @proxies.export(@object).should be(@proxy)
58
+ end
59
+
60
+ it "finds associated Ruby object on import" do
61
+ @proxies.import(@proxy).should be(@object)
62
+ end
63
+ end
64
+
65
+ describe "proxy matching" do
66
+ describe "when there are two related classes" do
67
+ before do
68
+ @A = Class.new
69
+ @B = Class.new(@A)
70
+ @A.class_eval do
71
+ attr_reader :native
72
+ def initialize(native = nil)
73
+ @native = native
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "and there is a proxy registered for the subclass but not the superclass" do
79
+ before do
80
+ @p = proxy_class
81
+ Proxies.register @B, @p
82
+ end
83
+
84
+ it "will create a proxy for the subclass" do
85
+ @proxies.export(@B.new).should be_kind_of(@p)
86
+ end
87
+
88
+ it "will create a native for the external class" do
89
+ internal = @proxies.import(@p.new)
90
+ internal.should be_kind_of(@B)
91
+ end
92
+
93
+ it "will fail to create a proxy for the superclass" do
94
+ expect {@proxies.export @A.new}.should raise_error(Jenkins::Plugin::ExportError)
95
+ end
96
+ end
97
+
98
+ describe "and there is a proxy registered for the superclass but not the superclass" do
99
+ before do
100
+ @p = proxy_class
101
+ Proxies.register @A, @p
102
+ end
103
+ it "will create a proxy for the superclass" do
104
+ @proxies.export(@A.new).should be_kind_of(@p)
105
+ @proxies.import(@p.new).should be_kind_of(@A)
106
+ end
107
+
108
+ it "will create a proxy for the subclass" do
109
+ @proxies.export(@B.new).should be_kind_of(@p)
110
+ end
111
+ end
112
+
113
+ describe "and there is proxy registered for both classes" do
114
+
115
+ before do
116
+ @pA = proxy_class
117
+ @pB = proxy_class
118
+ Proxies.register @A, @pA
119
+ Proxies.register @B, @pB
120
+ end
121
+ it "will create a proxy for the subclass with its registered proxy class" do
122
+ @proxies.export(@A.new).should be_kind_of(@pA)
123
+ @proxies.import(@pA.new).should be_kind_of(@A)
124
+ end
125
+
126
+ it "will create a proxy for the superclass with its registered proxy class" do
127
+ @proxies.export(@B.new).should be_kind_of(@pB)
128
+ @proxies.import(@pB.new).should be_kind_of(@B)
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ end
135
+
136
+ private
137
+
138
+ def proxy_class
139
+ cls = Class.new
140
+ cls.class_eval do
141
+ attr_reader :plugin, :object
142
+ def initialize(plugin = nil, object = nil)
143
+ @plugin, @object = plugin, object
144
+ end
145
+ end
146
+ return cls
147
+ end
148
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe "a class with #{Jenkins::Plugin::Proxy} mixed in" do
4
+
5
+ before do
6
+ @class = Class.new
7
+ @class.send(:include, Jenkins::Plugin::Proxy)
8
+ end
9
+
10
+ it "treats the plugin as transient" do
11
+ @class.transient?(:plugin).should be_true
12
+ end
13
+
14
+ it "leaves other fields alone" do
15
+ @class.transient?(:object).should be_false
16
+ end
17
+
18
+ describe "unmarshalling" do
19
+ before do
20
+ @class.class_eval do
21
+ attr_reader :plugin
22
+ end
23
+ @plugin = mock(Jenkins::Plugin)
24
+ @impl = impl = Object.new
25
+ @proxy = @class.allocate
26
+ @proxy.instance_eval do
27
+ @pluginid = "test-plugin"
28
+ @object = impl
29
+ end
30
+ @jenkins = mock(Java.jenkins.model.Jenkins)
31
+ @java_plugin = mock(:RubyPlugin, :getNativeRubyPlugin => @plugin)
32
+ @jenkins.stub(:getPlugin).with("test-plugin").and_return(@java_plugin)
33
+ Java.jenkins.model.Jenkins.stub(:getInstance).and_return(@jenkins)
34
+ end
35
+
36
+ it "reconstructs the @plugin field" do
37
+ @plugin.should_receive(:link).with(@impl, @proxy)
38
+ @proxy.read_completed
39
+ @proxy.plugin.should be(@plugin)
40
+ end
41
+ end
42
+
43
+ end