right_agent 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +78 -0
  3. data/Rakefile +86 -0
  4. data/lib/right_agent.rb +66 -0
  5. data/lib/right_agent/actor.rb +163 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +189 -0
  8. data/lib/right_agent/agent.rb +735 -0
  9. data/lib/right_agent/agent_config.rb +403 -0
  10. data/lib/right_agent/agent_identity.rb +209 -0
  11. data/lib/right_agent/agent_tags_manager.rb +213 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/broker_client.rb +683 -0
  14. data/lib/right_agent/command.rb +30 -0
  15. data/lib/right_agent/command/agent_manager_commands.rb +134 -0
  16. data/lib/right_agent/command/command_client.rb +136 -0
  17. data/lib/right_agent/command/command_constants.rb +42 -0
  18. data/lib/right_agent/command/command_io.rb +128 -0
  19. data/lib/right_agent/command/command_parser.rb +87 -0
  20. data/lib/right_agent/command/command_runner.rb +105 -0
  21. data/lib/right_agent/command/command_serializer.rb +63 -0
  22. data/lib/right_agent/console.rb +65 -0
  23. data/lib/right_agent/core_payload_types.rb +42 -0
  24. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  25. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  26. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  27. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  28. data/lib/right_agent/core_payload_types/dev_repositories.rb +90 -0
  29. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  30. data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
  31. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  32. data/lib/right_agent/core_payload_types/login_user.rb +62 -0
  33. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  34. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -0
  35. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  36. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  37. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +73 -0
  38. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  39. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  40. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  41. data/lib/right_agent/daemonize.rb +35 -0
  42. data/lib/right_agent/dispatcher.rb +348 -0
  43. data/lib/right_agent/enrollment_result.rb +217 -0
  44. data/lib/right_agent/exceptions.rb +30 -0
  45. data/lib/right_agent/ha_broker_client.rb +1278 -0
  46. data/lib/right_agent/idempotent_request.rb +140 -0
  47. data/lib/right_agent/log.rb +418 -0
  48. data/lib/right_agent/monkey_patches.rb +29 -0
  49. data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
  50. data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -0
  51. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  52. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  53. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  54. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  55. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  56. data/lib/right_agent/monkey_patches/ruby_patch/singleton_patch.rb +46 -0
  57. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -0
  58. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +90 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  64. data/lib/right_agent/multiplexer.rb +91 -0
  65. data/lib/right_agent/operation_result.rb +270 -0
  66. data/lib/right_agent/packets.rb +637 -0
  67. data/lib/right_agent/payload_formatter.rb +104 -0
  68. data/lib/right_agent/pid_file.rb +159 -0
  69. data/lib/right_agent/platform.rb +319 -0
  70. data/lib/right_agent/platform/darwin.rb +227 -0
  71. data/lib/right_agent/platform/linux.rb +268 -0
  72. data/lib/right_agent/platform/windows.rb +1204 -0
  73. data/lib/right_agent/scripts/agent_controller.rb +522 -0
  74. data/lib/right_agent/scripts/agent_deployer.rb +379 -0
  75. data/lib/right_agent/scripts/common_parser.rb +153 -0
  76. data/lib/right_agent/scripts/log_level_manager.rb +193 -0
  77. data/lib/right_agent/scripts/stats_manager.rb +256 -0
  78. data/lib/right_agent/scripts/usage.rb +58 -0
  79. data/lib/right_agent/secure_identity.rb +92 -0
  80. data/lib/right_agent/security.rb +32 -0
  81. data/lib/right_agent/security/cached_certificate_store_proxy.rb +63 -0
  82. data/lib/right_agent/security/certificate.rb +102 -0
  83. data/lib/right_agent/security/certificate_cache.rb +89 -0
  84. data/lib/right_agent/security/distinguished_name.rb +56 -0
  85. data/lib/right_agent/security/encrypted_document.rb +84 -0
  86. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  87. data/lib/right_agent/security/signature.rb +86 -0
  88. data/lib/right_agent/security/static_certificate_store.rb +69 -0
  89. data/lib/right_agent/sender.rb +937 -0
  90. data/lib/right_agent/serialize.rb +29 -0
  91. data/lib/right_agent/serialize/message_pack.rb +102 -0
  92. data/lib/right_agent/serialize/secure_serializer.rb +131 -0
  93. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  94. data/lib/right_agent/serialize/serializable.rb +135 -0
  95. data/lib/right_agent/serialize/serializer.rb +149 -0
  96. data/lib/right_agent/stats_helper.rb +731 -0
  97. data/lib/right_agent/subprocess.rb +38 -0
  98. data/lib/right_agent/tracer.rb +124 -0
  99. data/right_agent.gemspec +60 -0
  100. data/spec/actor_registry_spec.rb +81 -0
  101. data/spec/actor_spec.rb +99 -0
  102. data/spec/agent_config_spec.rb +226 -0
  103. data/spec/agent_identity_spec.rb +75 -0
  104. data/spec/agent_spec.rb +571 -0
  105. data/spec/broker_client_spec.rb +961 -0
  106. data/spec/command/agent_manager_commands_spec.rb +51 -0
  107. data/spec/command/command_io_spec.rb +93 -0
  108. data/spec/command/command_parser_spec.rb +79 -0
  109. data/spec/command/command_runner_spec.rb +72 -0
  110. data/spec/command/command_serializer_spec.rb +51 -0
  111. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  112. data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
  113. data/spec/core_payload_types/login_user_spec.rb +98 -0
  114. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  115. data/spec/core_payload_types/spec_helper.rb +23 -0
  116. data/spec/dispatcher_spec.rb +372 -0
  117. data/spec/enrollment_result_spec.rb +53 -0
  118. data/spec/ha_broker_client_spec.rb +1673 -0
  119. data/spec/idempotent_request_spec.rb +136 -0
  120. data/spec/log_spec.rb +177 -0
  121. data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
  122. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  123. data/spec/monkey_patches/string_patch_spec.rb +99 -0
  124. data/spec/multiplexer_spec.rb +48 -0
  125. data/spec/operation_result_spec.rb +171 -0
  126. data/spec/packets_spec.rb +418 -0
  127. data/spec/platform/platform_spec.rb +60 -0
  128. data/spec/results_mock.rb +45 -0
  129. data/spec/secure_identity_spec.rb +50 -0
  130. data/spec/security/cached_certificate_store_proxy_spec.rb +56 -0
  131. data/spec/security/certificate_cache_spec.rb +71 -0
  132. data/spec/security/certificate_spec.rb +49 -0
  133. data/spec/security/distinguished_name_spec.rb +46 -0
  134. data/spec/security/encrypted_document_spec.rb +55 -0
  135. data/spec/security/rsa_key_pair_spec.rb +55 -0
  136. data/spec/security/signature_spec.rb +66 -0
  137. data/spec/security/static_certificate_store_spec.rb +52 -0
  138. data/spec/sender_spec.rb +887 -0
  139. data/spec/serialize/message_pack_spec.rb +131 -0
  140. data/spec/serialize/secure_serializer_spec.rb +102 -0
  141. data/spec/serialize/serializable_spec.rb +90 -0
  142. data/spec/serialize/serializer_spec.rb +174 -0
  143. data/spec/spec.opts +2 -0
  144. data/spec/spec_helper.rb +77 -0
  145. data/spec/stats_helper_spec.rb +681 -0
  146. data/spec/tracer_spec.rb +114 -0
  147. metadata +320 -0
@@ -0,0 +1,131 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ module RightScale
26
+ class TestClass
27
+ include Serializable
28
+
29
+ attr_accessor :var1, :var2
30
+
31
+ def initialize(*a)
32
+ @var1 = a[0]
33
+ @var2 = a[1]
34
+ end
35
+
36
+ def serialized_members
37
+ [@var1, @var2]
38
+ end
39
+
40
+ def ==(rhs)
41
+ @var1 == rhs.var1 && @var2 == rhs.var2
42
+ end
43
+ end
44
+ end
45
+
46
+ class NonSerializableTestClass
47
+ attr_accessor :var1
48
+
49
+ def initialize(*a)
50
+ @var1 = a[0]
51
+ end
52
+
53
+ def to_msgpack(*a)
54
+ {
55
+ 'msgpack_class' => self.class.name,
56
+ 'data' => serialized_members
57
+ }.to_msgpack(*a)
58
+ end
59
+
60
+ def serialized_members
61
+ [@var1]
62
+ end
63
+ end
64
+
65
+ describe MessagePack do
66
+
67
+ it "should serialize an object when dump and unserialize when load to produce equivalent object" do
68
+ object = [1, 3.14, {"key" => "value"}]
69
+ MessagePack.load(MessagePack.dump(object)).should == object
70
+ end
71
+
72
+ it "should behave like JSON in terms of not preserving symbols" do
73
+ object = [1, 3.14, {:key => "value"}]
74
+ MessagePack.load(MessagePack.dump(object)).should == [1, 3.14, {"key" => "value"}]
75
+ end
76
+
77
+ it "should serialize arbitrary objects when dump and recreate when load" do
78
+ object = RightScale::TestClass.new({"key" => "value"}, [1, 2, "abc"])
79
+ data = MessagePack.dump(object)
80
+ (data =~ /msgpack_class.*RightScale::TestClass/).should be_true
81
+ MessagePack.load(data).should == object
82
+ end
83
+
84
+ it "should do nested creation of objects within arrays" do
85
+ test = RightScale::TestClass.new({"key" => "value"}, [1, 2, "abc"])
86
+ object = [1, 3.14, test]
87
+ data = MessagePack.dump(object)
88
+ (data =~ /msgpack_class.*RightScale::TestClass/).should be_true
89
+ MessagePack.load(data).should == object
90
+ end
91
+
92
+ it "should do nested creation of objects within hashes" do
93
+ test = RightScale::TestClass.new({"key" => "value"}, [1, 2, "abc"])
94
+ object = {"my_data" => [99, 4.3, 712345], "my_test" => test}
95
+ data = MessagePack.dump(object)
96
+ (data =~ /msgpack_class.*RightScale::TestClass/).should be_true
97
+ MessagePack.load(data).should == object
98
+ end
99
+
100
+ it "should do nested creation of objects recursively" do
101
+ test1 = RightScale::TestClass.new("some", "test")
102
+ test2 = RightScale::TestClass.new({"key" => "value"}, [1, 2, "abc"])
103
+ object = [{"my_data" => [99, 4.3, 712345], "my_tests" => {"test1" => test1, "test2" => test2}}, test1, test2]
104
+ data = MessagePack.dump(object)
105
+ (data =~ /msgpack_class.*RightScale::TestClass/).should be_true
106
+ MessagePack.load(data).should == object
107
+ end
108
+
109
+ it "should do nested creation of objects that are arguments in the creation of nested objects" do
110
+ test1 = RightScale::TestClass.new("some", "test")
111
+ test2 = RightScale::TestClass.new({"key" => "value"}, test1)
112
+ object = [{"my_data" => [99, 4.3, 712345], "my_tests" => {"test1" => test1, "test2" => test2}}, test1, test2]
113
+ data = MessagePack.dump(object)
114
+ (data =~ /msgpack_class.*RightScale::TestClass/).should be_true
115
+ MessagePack.load(data).should == object
116
+ end
117
+
118
+ it "should raise an exception if it finds a msgpack_class but there is no msgpack_generate method" do
119
+ data = MessagePack.dump(NonSerializableTestClass.new(nil))
120
+ (data =~ /msgpack_class.*NonSerializableTestClass/).should be_true
121
+ lambda { MessagePack.load(data) }.should raise_error(ArgumentError, /missing msgpack_create method/)
122
+ end
123
+
124
+ it "should raise an exception if it cannot resolve a named msgpack_class" do
125
+ object = [1, 3.14, {"msgpack_class" => "RightScale::BogusClass"}]
126
+ data = MessagePack.dump(object)
127
+ (data =~ /msgpack_class.*RightScale::BogusClass/).should be_true
128
+ lambda { MessagePack.load(data) }.should raise_error(ArgumentError, /Cannot find const/)
129
+ end
130
+
131
+ end
@@ -0,0 +1,102 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ module RightScale
26
+
27
+ # Add the ability to compare results for test purposes
28
+ class Result
29
+ def ==(other)
30
+ @token == other.token && @to == other.to && @from == other.from && @results == other.results
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ describe RightScale::SecureSerializer do
37
+
38
+ include RightScale::SpecHelper
39
+
40
+ before(:all) do
41
+ @certificate, @key = issue_cert
42
+ @store = RightScale::StaticCertificateStore.new(@certificate, @certificate)
43
+ @identity = "id"
44
+ end
45
+
46
+ it 'should raise when not initialized' do
47
+ data = RightScale::Result.new("token", "to", "from", ["results"])
48
+ lambda { RightScale::SecureSerializer.dump(data) }.should raise_error
49
+ end
50
+
51
+ it 'should raise when data not serialized with MessagePack or JSON' do
52
+ data = RightScale::Result.new("token", "to", "from", ["results"])
53
+ RightScale::SecureSerializer.init(RightScale::Serializer.new, @identity, @certificate, @key, @store, false)
54
+ lambda { RightScale::SecureSerializer.load(Marshal.dump(data)) }.should raise_error(RightScale::Serializer::SerializationError)
55
+ lambda { RightScale::SecureSerializer.load(YAML.dump(data)) }.should raise_error(RightScale::Serializer::SerializationError)
56
+ end
57
+
58
+ describe "using MessagePack" do
59
+
60
+ before(:each) do
61
+ flexmock(JSON).should_receive(:dump).never
62
+ flexmock(JSON).should_receive(:load).never
63
+ @data = RightScale::Result.new("token", "to", "from", ["results"], nil, nil, nil, nil, [12, 12])
64
+ end
65
+
66
+ it 'should unserialize signed data' do
67
+ RightScale::SecureSerializer.init(RightScale::Serializer.new, @identity, @certificate, @key, @store, false)
68
+ data = RightScale::SecureSerializer.dump(@data)
69
+ RightScale::SecureSerializer.load(data).should == @data
70
+ end
71
+
72
+ it 'should unserialize encrypted data' do
73
+ RightScale::SecureSerializer.init(RightScale::Serializer.new, @identity, @certificate, @key, @store, true)
74
+ data = RightScale::SecureSerializer.dump(@data)
75
+ RightScale::SecureSerializer.load(data).should == @data
76
+ end
77
+
78
+ end
79
+
80
+ describe "using JSON" do
81
+
82
+ before(:each) do
83
+ flexmock(MessagePack).should_receive(:dump).never
84
+ flexmock(MessagePack).should_receive(:load).never
85
+ @data = RightScale::Result.new("token", "to", "from", ["results"], nil, nil, nil, nil, [11, 11])
86
+ end
87
+
88
+ it 'should unserialize signed data' do
89
+ RightScale::SecureSerializer.init(RightScale::Serializer.new, @identity, @certificate, @key, @store, false)
90
+ data = RightScale::SecureSerializer.dump(@data)
91
+ RightScale::SecureSerializer.load(data).should == @data
92
+ end
93
+
94
+ it 'should unserialize encrypted data' do
95
+ RightScale::SecureSerializer.init(RightScale::Serializer.new, @identity, @certificate, @key, @store, true)
96
+ data = RightScale::SecureSerializer.dump(@data)
97
+ RightScale::SecureSerializer.load(data).should == @data
98
+ end
99
+
100
+ end
101
+
102
+ end
@@ -0,0 +1,90 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+ require 'json/ext'
25
+
26
+ class TestClass1
27
+
28
+ include RightScale::Serializable
29
+
30
+ attr_accessor :name, :array, :date
31
+
32
+ def initialize(*args)
33
+ @name = args[0] if args.size > 0
34
+ @array = args[1] if args.size > 1
35
+ @date = args[2] if args.size > 2
36
+ end
37
+
38
+ def serialized_members
39
+ [@name, @array, @date]
40
+ end
41
+ end
42
+
43
+ class TestClass2
44
+
45
+ include RightScale::Serializable
46
+
47
+ attr_accessor :attr1, :attr2
48
+
49
+ def initialize(*args)
50
+ attr1 = args[0]
51
+ attr2 = args[1] if args.size > 1
52
+ end
53
+
54
+ def serialized_members
55
+ [@attr1, @attr2]
56
+ end
57
+
58
+ end
59
+
60
+ describe RightScale::Serializable do
61
+
62
+ it 'should serialize using MessagePack' do
63
+ a1 = TestClass1.new
64
+ a1.name = "Test1"
65
+ a1.array = ["some", "stuff" ]
66
+
67
+ b1 = TestClass1.new
68
+ b1.name = "Test2"
69
+ b1.array = ["some", "more", "stuff"]
70
+
71
+ c = TestClass2.new([a1, b1], 1234)
72
+ a1.to_msgpack
73
+ TestClass2.msgpack_create(c.to_msgpack).should == c
74
+ end
75
+
76
+ it 'should serialize using JSON' do
77
+ a1 = TestClass1.new
78
+ a1.name = "Test1"
79
+ a1.array = ["some", "stuff" ]
80
+
81
+ b1 = TestClass1.new
82
+ b1.name = "Test2"
83
+ b1.array = ["some", "more", "stuff"]
84
+
85
+ c = TestClass2.new([a1, b1], 1234)
86
+ a1.to_json
87
+ TestClass2.json_create(c.to_msgpack).should == c
88
+ end
89
+
90
+ end
@@ -0,0 +1,174 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
24
+
25
+ describe RightScale::Serializer do
26
+
27
+ describe "Format" do
28
+
29
+ it "supports MessagePack format" do
30
+ [ :msgpack, "msgpack" ].each do |format|
31
+ lambda { RightScale::Serializer.new(format).format.should == :msgpack }.should_not raise_error
32
+ end
33
+ end
34
+
35
+ it "supports JSON format" do
36
+ [ :json, "json" ].each do |format|
37
+ lambda { RightScale::Serializer.new(format).format.should == :json }.should_not raise_error
38
+ end
39
+ end
40
+
41
+ it "supports secure format" do
42
+ [ :secure, "secure" ].each do |format|
43
+ lambda { RightScale::Serializer.new(format).format.should == :secure }.should_not raise_error
44
+ end
45
+ end
46
+
47
+ it "should default to MessagePack format if none specified" do
48
+ RightScale::Serializer.new.format.should == :msgpack
49
+ end
50
+
51
+ it "should raise error if unsupported format specified" do
52
+ lambda { RightScale::Serializer.new(:yaml) }.should raise_error(ArgumentError)
53
+ end
54
+
55
+ end # Format
56
+
57
+ describe "Serialization" do
58
+
59
+ it "should use MessagePack as default serializer and not cascade to others" do
60
+ serializer = RightScale::Serializer.new
61
+ flexmock(serializer).should_receive(:cascade_serializers).with(:dump, "hello", [MessagePack]).once
62
+ serializer.dump("hello")
63
+ end
64
+
65
+ it "should use preferred serializer if specified and not cascade to others" do
66
+ serializer = RightScale::Serializer.new(:json)
67
+ flexmock(serializer).should_receive(:cascade_serializers).with(:dump, "hello", [JSON]).once
68
+ serializer.dump("hello")
69
+ end
70
+
71
+ it "should raise SerializationError if packet could not be serialized and not try other serializer" do
72
+ flexmock(MessagePack).should_receive(:dump).with("hello").and_raise(StandardError).once
73
+ flexmock(JSON).should_receive(:dump).with("hello").and_raise(StandardError).once
74
+ serializer = RightScale::Serializer.new(:msgpack)
75
+ lambda { serializer.dump("hello") }.should raise_error(RightScale::Serializer::SerializationError)
76
+ serializer = RightScale::Serializer.new(:json)
77
+ lambda { serializer.dump("hello") }.should raise_error(RightScale::Serializer::SerializationError)
78
+ end
79
+
80
+ it "should return serialized packet" do
81
+ serialized_packet = flexmock("Packet")
82
+ flexmock(MessagePack).should_receive(:dump).with("hello").and_return(serialized_packet).once
83
+ serializer = RightScale::Serializer.new
84
+ serializer.dump("hello").should == serialized_packet
85
+ end
86
+
87
+ it "should be able to override preferred format" do
88
+ serializer = RightScale::Serializer.new(:json)
89
+ flexmock(serializer).should_receive(:cascade_serializers).with(:dump, "hello", [MessagePack]).once
90
+ flexmock(serializer).should_receive(:cascade_serializers).with(:dump, "hello", [JSON]).never
91
+ serializer.dump("hello", :msgpack)
92
+ end
93
+
94
+ it "should not be able to override preferred format when secure" do
95
+ serializer = RightScale::Serializer.new(:secure)
96
+ flexmock(serializer).should_receive(:cascade_serializers).with(:dump, "hello", [RightScale::SecureSerializer]).once
97
+ flexmock(serializer).should_receive(:cascade_serializers).with(:dump, "hello", [MessagePack]).never
98
+ serializer.dump("hello", :msgpack)
99
+ end
100
+
101
+ describe "MessagePack for common classes" do
102
+
103
+ it "should serialize Date object" do
104
+ serializer = RightScale::Serializer.new(:msgpack)
105
+ date = Date.today
106
+ data = serializer.dump(date)
107
+ Date.parse(serializer.load(data)).should == date
108
+ end
109
+
110
+ it "should serialize Time object" do
111
+ serializer = RightScale::Serializer.new(:msgpack)
112
+ time = Time.now
113
+ data = serializer.dump(time)
114
+ Time.parse(serializer.load(data)).to_i.should == time.to_i
115
+ end
116
+
117
+ it "should serialize DateTime object" do
118
+ serializer = RightScale::Serializer.new(:msgpack)
119
+ date_time = DateTime.now
120
+ data = serializer.dump(date_time)
121
+ DateTime.parse(serializer.load(data)).to_s.should == date_time.to_s
122
+ end
123
+
124
+ end
125
+
126
+ end # Serialization of Packet
127
+
128
+ describe "Unserialization" do
129
+
130
+ it "should cascade through available serializers" do
131
+ serializer = RightScale::Serializer.new
132
+ flexmock(serializer).should_receive(:cascade_serializers).with(:load, "olleh", [JSON, MessagePack]).once
133
+ serializer.load("olleh")
134
+ end
135
+
136
+ it "should try all supported formats (MessagePack, JSON)" do
137
+ flexmock(MessagePack).should_receive(:load).with("olleh").and_raise(StandardError).once
138
+ flexmock(JSON).should_receive(:load).with("olleh").and_raise(StandardError).once
139
+ lambda { RightScale::Serializer.new.load("olleh") }.should raise_error(RightScale::Serializer::SerializationError)
140
+ end
141
+
142
+ it "should try JSON format first if looks like JSON even if MessagePack preferred" do
143
+ object = [1, 2, 3]
144
+ serialized = object.to_json
145
+ flexmock(MessagePack).should_receive(:load).with(serialized).never
146
+ flexmock(JSON).should_receive(:load).with(serialized).and_return(object).once
147
+ RightScale::Serializer.new(:msgpack).load(serialized)
148
+ end
149
+
150
+ it "should try MessagePack format first if looks like MessagePack even if JSON preferred" do
151
+ object = [1, 2, 3]
152
+ serialized = object.to_msgpack
153
+ flexmock(JSON).should_receive(:load).with(serialized).never
154
+ flexmock(MessagePack).should_receive(:load).with(serialized).and_return(object).once
155
+ RightScale::Serializer.new(:json).load(serialized)
156
+ end
157
+
158
+ it "should raise SerializationError if packet could not be unserialized" do
159
+ flexmock(MessagePack).should_receive(:load).with("olleh").and_raise(StandardError).once
160
+ flexmock(JSON).should_receive(:load).with("olleh").and_raise(StandardError).once
161
+ serializer = RightScale::Serializer.new
162
+ lambda { serializer.load("olleh") }.should raise_error(RightScale::Serializer::SerializationError)
163
+ end
164
+
165
+ it "should return unserialized packet" do
166
+ unserialized_packet = flexmock("Packet")
167
+ flexmock(MessagePack).should_receive(:load).with("olleh").and_return(unserialized_packet).once
168
+ serializer = RightScale::Serializer.new(:msgpack)
169
+ serializer.load("olleh").should == unserialized_packet
170
+ end
171
+
172
+ end # De-Serialization of Packet
173
+
174
+ end # RightScale::Serializer