store_agent 1.0.0

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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +5 -0
  6. data/LICENSE +202 -0
  7. data/README.md +433 -0
  8. data/Rakefile +2 -0
  9. data/lib/store_agent.rb +31 -0
  10. data/lib/store_agent/config.rb +152 -0
  11. data/lib/store_agent/data_encoder.rb +32 -0
  12. data/lib/store_agent/data_encoder/gzip_encoder.rb +50 -0
  13. data/lib/store_agent/data_encoder/openssl_aes_256_cbc_encoder.rb +65 -0
  14. data/lib/store_agent/exceptions.rb +87 -0
  15. data/lib/store_agent/node.rb +26 -0
  16. data/lib/store_agent/node/attachment.rb +93 -0
  17. data/lib/store_agent/node/attachment/metadata.rb +120 -0
  18. data/lib/store_agent/node/attachment/permission.rb +121 -0
  19. data/lib/store_agent/node/object.rb +233 -0
  20. data/lib/store_agent/node/object/directory_object.rb +264 -0
  21. data/lib/store_agent/node/object/file_object.rb +197 -0
  22. data/lib/store_agent/node/object/virtual_object.rb +25 -0
  23. data/lib/store_agent/node/prepend_module/locker.rb +125 -0
  24. data/lib/store_agent/node/prepend_module/path_validator.rb +138 -0
  25. data/lib/store_agent/node/prepend_module/permission_checker.rb +96 -0
  26. data/lib/store_agent/user.rb +111 -0
  27. data/lib/store_agent/validator.rb +60 -0
  28. data/lib/store_agent/version.rb +19 -0
  29. data/lib/store_agent/version_manager.rb +101 -0
  30. data/lib/store_agent/version_manager/ruby_git.rb +100 -0
  31. data/lib/store_agent/version_manager/rugged_git.rb +133 -0
  32. data/lib/store_agent/workspace.rb +88 -0
  33. data/spec/spec_helper.rb +47 -0
  34. data/spec/store_agent/data_encoder/encoder_shared_context.rb +74 -0
  35. data/spec/store_agent/data_encoder/gzip_encoder_spec.rb +41 -0
  36. data/spec/store_agent/data_encoder/openssl_aes_256_cbc_encoder_spec.rb +42 -0
  37. data/spec/store_agent/data_encoder_spec.rb +78 -0
  38. data/spec/store_agent/node/directory_object_spec.rb +563 -0
  39. data/spec/store_agent/node/file_object_spec.rb +379 -0
  40. data/spec/store_agent/node/locker_spec.rb +191 -0
  41. data/spec/store_agent/node/metadata_spec.rb +339 -0
  42. data/spec/store_agent/node/object_spec.rb +73 -0
  43. data/spec/store_agent/node/path_validator_spec.rb +121 -0
  44. data/spec/store_agent/node/permission_spec.rb +232 -0
  45. data/spec/store_agent/user_spec.rb +127 -0
  46. data/spec/store_agent/version_manager/git_shared_context.rb +286 -0
  47. data/spec/store_agent/version_manager/ruby_git_spec.rb +32 -0
  48. data/spec/store_agent/version_manager/rugged_git_spec.rb +32 -0
  49. data/spec/store_agent/workspace_spec.rb +107 -0
  50. data/spec/store_agent_spec.rb +53 -0
  51. data/store_agent.gemspec +33 -0
  52. metadata +252 -0
@@ -0,0 +1,232 @@
1
+ #--
2
+ # Copyright 2015 realglobe, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require "spec_helper"
18
+
19
+ RSpec.describe StoreAgent::Node::Permission do
20
+ let :super_user do
21
+ StoreAgent::Superuser.new
22
+ end
23
+ let :owner do
24
+ StoreAgent::User.new("owner_uid")
25
+ end
26
+ let :user do
27
+ StoreAgent::User.new("user_id")
28
+ end
29
+ let :group_user do
30
+ StoreAgent::User.new("owner_uid", "group")
31
+ end
32
+ let :namespaced_user do
33
+ StoreAgent::User.new(["user_id", "namespaced_id"])
34
+ end
35
+ let :guest do
36
+ StoreAgent::Guest.new
37
+ end
38
+ let :workspace do
39
+ owner.workspace(workspace_name)
40
+ end
41
+
42
+ context "パーミッションのテスト" do
43
+ let :workspace_name do
44
+ "permission_workspace"
45
+ end
46
+ before do
47
+ if !workspace.exists?
48
+ workspace.create
49
+ owner.workspace(workspace_name).directory("foo").create
50
+ owner.workspace(workspace_name).file("foo/bar.txt").create("body" => "1234567890")
51
+ owner.workspace(workspace_name).file("foo/hoge.txt").create("body" => "0987654321")
52
+ end
53
+ @root_node = workspace.directory("/")
54
+ end
55
+
56
+ context "Workspace 作成直後のパーミッション" do
57
+ it "Superuser には全権限がある" do
58
+ node = super_user.workspace(workspace_name).directory("/")
59
+ expect(node.permission.allow?("read")).to be true
60
+ expect(node.permission.allow?("write")).to be true
61
+ end
62
+ it "Workspace の作成者には全権限がある" do
63
+ expect(@root_node.permission.allow?("read")).to be true
64
+ expect(@root_node.permission.allow?("write")).to be true
65
+ end
66
+ it "ID に Workspace の作成者の ID を含む場合、権限がある" do
67
+ node = group_user.workspace(workspace_name).root
68
+ expect(node.permission.allow?("read")).to be true
69
+ expect(node.permission.allow?("write")).to be true
70
+ end
71
+ it "ゲスト User には全権限が無い" do
72
+ node = guest.workspace(workspace_name).directory("/")
73
+ expect(node.permission.allow?("read")).to be false
74
+ expect(node.permission.allow?("write")).to be false
75
+ end
76
+ end
77
+ context "ID が配列のユーザーで Workspace を作成する" do
78
+ before do
79
+ @namespaced_workspace = namespaced_user.workspace("permission_workspace_namespaced_id")
80
+ if !@namespaced_workspace.exists?
81
+ @namespaced_workspace.create
82
+ end
83
+ @root_node = @namespaced_workspace.root
84
+ end
85
+
86
+ it "権限情報はネストしたハッシュになる" do
87
+ expect(@root_node.permission.data["users"]["user_id"]["namespaced_id"]["read"]).to eq true
88
+ expect(@root_node.permission.data["users"]["user_id"]["namespaced_id"]["write"]).to eq true
89
+ end
90
+ it "Superuser には権限がある" do
91
+ node = super_user.workspace("permission_workspace_namespaced_id").directory("/")
92
+ expect(node.permission.allow?("read")).to be true
93
+ expect(node.permission.allow?("write")).to be true
94
+ end
95
+ it "Workspace の作成者には権限がある" do
96
+ expect(@root_node.permission.allow?("read")).to be true
97
+ expect(@root_node.permission.allow?("write")).to be true
98
+ end
99
+ it "User には権限が無い" do
100
+ node = user.workspace("permission_workspace_namespaced_id").directory("/")
101
+ expect(node.permission.allow?("read")).to be false
102
+ expect(node.permission.allow?("write")).to be false
103
+ end
104
+ end
105
+
106
+ context "パーミッションの変更" do
107
+ before do
108
+ dir = owner.workspace(workspace_name).directory("bar")
109
+ if !dir.exists?
110
+ dir.create
111
+ owner.workspace(workspace_name).file("bar/fuga.txt").create("body" => "1234567890")
112
+ end
113
+ end
114
+
115
+ it "ファイルの権限を変更する" do
116
+ owner.workspace(workspace_name).file("bar/hoge.txt").create("body" => "1234567890")
117
+ owner.workspace(workspace_name).file("bar/hoge.txt").set_permission(identifier: "user_id", permission_values: {"read" => true})
118
+ expect(user.workspace(workspace_name).file("bar/hoge.txt").permission.allow?("read")).to be true
119
+ expect(user.workspace(workspace_name).file("bar/hoge.txt").permission.data["users"]["user_id"]).to eq ({"read" => true})
120
+ owner.workspace(workspace_name).file("bar/hoge.txt").set_permission(identifier: "user_id", permission_values: {"read" => false})
121
+ expect(user.workspace(workspace_name).file("bar/hoge.txt").permission.allow?("read")).to be false
122
+ owner.workspace(workspace_name).file("bar/hoge.txt").set_permission(identifier: "user_id", permission_values: {"read" => true})
123
+ owner.workspace(workspace_name).file("bar/hoge.txt").unset_permission(identifier: "user_id", permission_names: "read")
124
+ expect(user.workspace(workspace_name).file("bar/hoge.txt").permission.allow?("read")).to be false
125
+ expect(user.workspace(workspace_name).file("bar/hoge.txt").permission.data["users"].key?("user_id")).to eq false
126
+ end
127
+ it "ディレクトリの単独の権限を変更した場合、配下ファイルの権限は変わらない" do
128
+ owner.workspace(workspace_name).directory("bar").set_permission(identifier: "user_id", permission_values: {"write" => true})
129
+ expect(user.workspace(workspace_name).file("bar/fuga.txt").permission.allow?("write")).to be false
130
+ owner.workspace(workspace_name).directory("bar").set_permission(identifier: "user_id", permission_values: {"write" => false})
131
+ expect(user.workspace(workspace_name).file("bar/fuga.txt").permission.allow?("write")).to be false
132
+ owner.workspace(workspace_name).directory("bar").set_permission(identifier: "user_id", permission_values: {"write" => true}, recursive: true)
133
+ owner.workspace(workspace_name).directory("bar").unset_permission(identifier: "user_id", permission_names: "write")
134
+ expect(user.workspace(workspace_name).file("bar/fuga.txt").permission.allow?("write")).to be true
135
+ end
136
+ it "サブツリー全体の権限を変更した場合、配下ファイルの権限も変更される" do
137
+ owner.workspace(workspace_name).directory("bar").set_permission(identifier: "user_id", permission_values: {"execute" => true}, recursive: true)
138
+ expect(user.workspace(workspace_name).file("bar/fuga.txt").permission.allow?("execute")).to be true
139
+ owner.workspace(workspace_name).directory("bar").set_permission(identifier: "user_id", permission_values: {"execute" => false}, recursive: true)
140
+ expect(user.workspace(workspace_name).file("bar/fuga.txt").permission.allow?("execute")).to be false
141
+ owner.workspace(workspace_name).directory("bar").set_permission(identifier: "user_id", permission_values: {"execute" => true}, recursive: true)
142
+ owner.workspace(workspace_name).directory("bar").unset_permission(identifier: "user_id", permission_names: "execute", recursive: true)
143
+ expect(user.workspace(workspace_name).file("bar/fuga.txt").permission.allow?("execute")).to be false
144
+ end
145
+ it "ID が配列のユーザーに対して権限を変更する" do
146
+ owner.workspace(workspace_name).file("namespaced.txt").create
147
+ owner.workspace(workspace_name).file("namespaced.txt").set_permission(identifier: ["user_id", "namespaced_id"], permission_values: {"chmod" => true}, recursive: true)
148
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.allow?("chmod")).to be true
149
+ expect(user.workspace(workspace_name).file("namespaced.txt").permission.allow?("chmod")).to be false
150
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.data["users"]["user_id"]).to eq ({"namespaced_id" => {"chmod" => true}})
151
+ owner.workspace(workspace_name).file("namespaced.txt").unset_permission(identifier: ["user_id", "namespaced_id"], permission_names: "chown")
152
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.allow?("chmod")).to be true
153
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.allow?("chown")).to be false
154
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.data["users"]["user_id"]).to eq ({"namespaced_id" => {"chmod" => true}})
155
+ owner.workspace(workspace_name).file("namespaced.txt").unset_permission(identifier: ["user_id", "namespaced_id"], permission_names: "chmod")
156
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.allow?("chmod")).to be false
157
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.data["users"]["user_id"]).to eq nil
158
+ owner.workspace(workspace_name).file("namespaced.txt").set_permission(identifier: ["deep", "nested", "namespace"], permission_values: {})
159
+ expect(namespaced_user.workspace(workspace_name).file("namespaced.txt").permission.data["users"]["user_id"]).to eq nil
160
+ owner.workspace(workspace_name).file("namespaced.txt").set_permission(identifier: ["user_id", "deep", "nested", "namespace"], permission_values: {"read" => true})
161
+ end
162
+ end
163
+
164
+ context "Superuser" do
165
+ it "ディレクトリを作成できる" do
166
+ expect(super_user.workspace(workspace_name).directory("foo/super_user_dir").create)
167
+ end
168
+ it "ファイルを読める" do
169
+ expect(super_user.workspace(workspace_name).file("foo/bar.txt").read).to eq "1234567890"
170
+ end
171
+ it "ファイルを作成できる" do
172
+ expect(super_user.workspace(workspace_name).file("foo/super_user.txt").create("body" => ""))
173
+ end
174
+ end
175
+ context "Owner" do
176
+ it "ディレクトリを作成できる" do
177
+ expect(owner.workspace(workspace_name).directory("foo/owner_dir").create)
178
+ end
179
+ it "ファイルを読める" do
180
+ expect(owner.workspace(workspace_name).file("foo/bar.txt").read).to eq "1234567890"
181
+ end
182
+ it "ファイルを作成できる" do
183
+ expect(owner.workspace(workspace_name).file("foo/owner.txt").create("body" => ""))
184
+ end
185
+ end
186
+ context "User" do
187
+ it "ディレクトリを作成できない" do
188
+ expect do
189
+ user.workspace(workspace_name).directory("foo/user_dir").create
190
+ end.to raise_error
191
+ end
192
+ it "ファイルを読めない" do
193
+ expect do
194
+ user.workspace(workspace_name).file("foo/bar.txt").read
195
+ end.to raise_error
196
+ end
197
+ it "ファイルを作成できない" do
198
+ expect do
199
+ user.workspace(workspace_name).file("foo/user.txt").create("body" => "")
200
+ end.to raise_error
201
+ end
202
+ it "権限を付与されればファイルを読めるようになる" do
203
+ owner.workspace(workspace_name).file("foo/hoge.txt").set_permission(identifier: "user_id", permission_values: {"read" => true})
204
+ expect(user.workspace(workspace_name).file("foo/hoge.txt").read).to eq "0987654321"
205
+ end
206
+ end
207
+ context "User(namespaced)" do
208
+ it "ディレクトリを作成できない" do
209
+ expect do
210
+ namespaced_user.workspace(workspace_name).directory("foo/namespaced_user_dir").create
211
+ end.to raise_error
212
+ end
213
+ end
214
+ context "Guest" do
215
+ it "ディレクトリを作成できない" do
216
+ expect do
217
+ guest.workspace(workspace_name).directory("foo/guest_dir").create
218
+ end.to raise_error
219
+ end
220
+ it "ファイルを読めない" do
221
+ expect do
222
+ guest.workspace(workspace_name).file("foo/bar.txt").read
223
+ end.to raise_error
224
+ end
225
+ it "ファイルを作成できない" do
226
+ expect do
227
+ guest.workspace(workspace_name).file("foo/guest.txt").create("body" => "")
228
+ end.to raise_error
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,127 @@
1
+ #--
2
+ # Copyright 2015 realglobe, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require "spec_helper"
18
+
19
+ RSpec.describe StoreAgent::User do
20
+ context "初期化のテスト" do
21
+ context "一般 User の初期化" do
22
+ context "作成成功するケース" do
23
+ it "パラメータに文字列が渡された場合、一般ユーザーになる" do
24
+ expect(StoreAgent::User.new("hoge").guest?).to be false
25
+ end
26
+ it "パラメータが文字列またはシンボルなら文字列に変換されて User 作成される" do
27
+ expect(StoreAgent::User.new("hoge").identifiers).to eq ["hoge"]
28
+ expect(StoreAgent::User.new(:foo, :bar).identifiers).to eq ["foo", "bar"]
29
+ end
30
+ it "パラメータが配列を含む場合、要素が一つだけの配列は文字列に変換される" do
31
+ expect(StoreAgent::User.new("hoge", ["foo"]).identifiers).to eq ["hoge", "foo"]
32
+ expect(StoreAgent::User.new("hoge", [:foo]).identifiers).to eq ["hoge", "foo"]
33
+ end
34
+ it "パラメータが配列を含む場合、要素が二つ以上なら identifiers に配列として追加される" do
35
+ expect(StoreAgent::User.new("hoge", [:foo, "bar"]).identifiers).to eq ["hoge", ["foo", "bar"]]
36
+ end
37
+ it "パラメータの最後が要素が二つ以上の配列の場合、その先頭要素が identifier になる" do
38
+ expect(StoreAgent::User.new("hoge", [:foo, "bar"]).identifier).to eq "foo"
39
+ end
40
+ it "一般の User は super_user? ではない" do
41
+ expect(StoreAgent::User.new("foo").super_user?).to be false
42
+ end
43
+ end
44
+
45
+ context "作成失敗するケース" do
46
+ it "パラメータが無い User を作成しようとするとエラーになる" do
47
+ expect do
48
+ StoreAgent::User.new
49
+ end.to raise_error(ArgumentError)
50
+ end
51
+ it "パラメータが文字列やシンボル、その配列でない場合はエラーになる" do
52
+ expect do
53
+ StoreAgent::User.new(foo: :bar)
54
+ end.to raise_error
55
+ end
56
+ it "パラメータの要素に空文字列が含まれる User は作成できない" do
57
+ expect do
58
+ StoreAgent::User.new("hoge", "")
59
+ end.to raise_error
60
+ end
61
+ it "パラメータの要素に空シンボルが含まれる User は作成できない" do
62
+ expect do
63
+ StoreAgent::User.new("hoge", :"")
64
+ end.to raise_error
65
+ end
66
+ it "パラメータの要素に空配列が含まれる User は作成できない" do
67
+ expect do
68
+ StoreAgent::User.new("hoge", [])
69
+ end.to raise_error
70
+ end
71
+ it "パラメータの要素に文字列やシンボル以外が含まれる User は作成できない" do
72
+ expect do
73
+ StoreAgent::User.new("hoge", false)
74
+ end.to raise_error
75
+ expect do
76
+ StoreAgent::User.new(0)
77
+ end.to raise_error
78
+ end
79
+ it "パラメータに / が入っている文字列が含まれる User は作成できない" do
80
+ expect do
81
+ StoreAgent::User.new("foo/bar", "hoge")
82
+ end.to raise_error
83
+ end
84
+ it "パラメータに Superuser の identifier が含まれる User は作成できない" do
85
+ expect do
86
+ StoreAgent::User.new("hoge", "root")
87
+ end.to raise_error
88
+ expect do
89
+ StoreAgent::User.new("hoge", :root)
90
+ end.to raise_error
91
+ end
92
+ it "パラメータに Guest の identifier が含まれる User は作成できない" do
93
+ expect do
94
+ StoreAgent::User.new("hoge", "nobody")
95
+ end.to raise_error
96
+ expect do
97
+ StoreAgent::User.new("hoge", :nobody)
98
+ end.to raise_error
99
+ end
100
+ end
101
+ end
102
+
103
+ context "Superuser の初期化" do
104
+ it "Superuser はパラメータ無しでも作成できる" do
105
+ expect(StoreAgent::Superuser.new.identifiers).to eq ["root"]
106
+ end
107
+ it "Superuser はパラメータを渡しても無視される" do
108
+ expect(StoreAgent::Superuser.new(:foo).identifiers).to eq ["root"]
109
+ end
110
+ it "Superuser は super_user?" do
111
+ expect(StoreAgent::Superuser.new.super_user?).to be true
112
+ end
113
+ end
114
+
115
+ context "Guest の初期化" do
116
+ it "Guest はパラメータ無しでも作成できる" do
117
+ expect(StoreAgent::Guest.new.identifiers).to eq ["nobody"]
118
+ end
119
+ it "Guest はパラメータを渡しても無視される" do
120
+ expect(StoreAgent::Guest.new(:foo).identifiers).to eq ["nobody"]
121
+ end
122
+ it "Guest は guest?" do
123
+ expect(StoreAgent::Guest.new.guest?).to be true
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,286 @@
1
+ #--
2
+ # Copyright 2015 realglobe, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ RSpec.shared_context "git" do
18
+ after :all do
19
+ StoreAgent.configure do |c|
20
+ c.version_manager = StoreAgent::VersionManager
21
+ end
22
+ end
23
+ let :user do
24
+ StoreAgent::User.new("foo")
25
+ end
26
+ let :workspace do
27
+ user.workspace(workspace_name)
28
+ end
29
+ context "workspaceの初期化" do
30
+ let :workspace do
31
+ user.workspace("#{workspace_name}_create_workspace")
32
+ end
33
+
34
+ it ".gitが作成される" do
35
+ workspace.create
36
+ expect(File.exists?("/tmp/store_agent/#{workspace_name}_create_workspace/.git")).to be true
37
+ end
38
+ end
39
+ context "オブジェクトの作成/更新/削除" do
40
+ before do
41
+ if !workspace.exists?
42
+ workspace.create
43
+ end
44
+ end
45
+
46
+ it "ディレクトリの作成" do
47
+ workspace.directory("create").create
48
+ scoped_commit_id = workspace.version_manager.revisions("storage/create").first
49
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
50
+ end
51
+ it "ファイルの作成" do
52
+ workspace.file("create_test.txt").create
53
+ scoped_commit_id = workspace.version_manager.revisions("storage/create_test.txt").first
54
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
55
+ end
56
+ it "ファイルの更新" do
57
+ workspace.file("update_test.txt").create
58
+ workspace.file("update_test.txt").update("updated")
59
+ scoped_commit_id = workspace.version_manager.revisions("storage/update_test.txt").first
60
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
61
+ end
62
+ it "ディレクトリの削除" do
63
+ workspace.directory("delete").create
64
+ workspace.directory("delete").delete
65
+ scoped_commit_id = workspace.version_manager.revisions("storage/delete").first
66
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
67
+ end
68
+ it "ファイルの削除" do
69
+ workspace.file("delete_test.txt").create
70
+ workspace.file("delete_test.txt").delete
71
+ scoped_commit_id = workspace.version_manager.revisions("storage/delete_test.txt").first
72
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
73
+ end
74
+ it "ファイルの更新途中で例外が発生した場合、ロールバックされる" do
75
+ file = workspace.file("rollback_test.txt")
76
+ file.create
77
+ class << file.metadata
78
+ def update(*)
79
+ raise
80
+ end
81
+ end
82
+ begin
83
+ file.update("updated")
84
+ rescue
85
+ end
86
+ scoped_commit_id = workspace.version_manager.revisions("storage/rollback_test.txt").first
87
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
88
+ expect(workspace.file("rollback_test.txt").read).to eq ""
89
+ end
90
+ it ".gitignore が作成されても、その中身はファイルのバージョン管理時には無視される" do
91
+ workspace.file(".gitignore").create("*\n")
92
+ workspace.directory("ignore").create
93
+ scoped_commit_id = workspace.version_manager.revisions("storage/ignore").first
94
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
95
+ workspace.file("ignore/tmp.txt").create
96
+ scoped_commit_id = workspace.version_manager.revisions("storage/ignore/tmp.txt").first
97
+ expect(scoped_commit_id).to eq workspace.version_manager.revisions.first
98
+ end
99
+ end
100
+ context "予約されているファイル/ディレクトリ名は操作できない" do
101
+ let :workspace do
102
+ user.workspace("#{workspace_name}_reserved_name")
103
+ end
104
+ before do
105
+ if !workspace.exists?
106
+ workspace.create
107
+ end
108
+ end
109
+
110
+ context "create できない" do
111
+ it "名前が .git のディレクトリ" do
112
+ begin
113
+ workspace.directory(".git").create
114
+ rescue
115
+ end
116
+ expect(workspace.directory(".git").exists?).to be false
117
+ end
118
+ it "名前が .git のファイル" do
119
+ begin
120
+ workspace.file(".git").create
121
+ rescue
122
+ end
123
+ expect(workspace.file(".git").exists?).to be false
124
+ end
125
+ it "名前が .keep のディレクトリ" do
126
+ expect do
127
+ workspace.directory(".keep").create
128
+ end.to raise_error(StoreAgent::InvalidPathError)
129
+ end
130
+ it "名前が .keep のファイル" do
131
+ expect do
132
+ workspace.file(".keep").create
133
+ end.to raise_error(StoreAgent::InvalidPathError)
134
+ end
135
+ end
136
+ context "read できない" do
137
+ it "名前が .git のディレクトリ" do
138
+ expect do
139
+ workspace.directory(".git").read
140
+ end.to raise_error(StoreAgent::InvalidPathError)
141
+ end
142
+ end
143
+ context "update できない" do
144
+ it "名前が .keep のファイル" do
145
+ expect do
146
+ workspace.file(".keep").update("keep it")
147
+ end.to raise_error(StoreAgent::InvalidPathError)
148
+ end
149
+ end
150
+ context "delete できない" do
151
+ it "名前が .git のディレクトリ" do
152
+ expect do
153
+ workspace.directory(".git").delete
154
+ end.to raise_error(StoreAgent::InvalidPathError)
155
+ end
156
+ end
157
+ end
158
+ context "過去のオブジェクトの取得" do
159
+ before do
160
+ if !workspace.exists?
161
+ workspace.create
162
+ end
163
+ if !(dir = workspace.directory("revision")).exists?
164
+ dir.create
165
+ end
166
+ end
167
+
168
+ it "適切なバージョンを指定すれば、変更前のディレクトリのファイル一覧が取得できる" do
169
+ workspace.directory("revision/delete").create
170
+ workspace.directory("revision/delete/tmp").create
171
+ revision = workspace.version_manager.revisions.first
172
+ workspace.directory("revision/delete/tmp").delete
173
+ expect(workspace.directory("revision/delete").read(revision: revision)).to eq ["tmp"]
174
+ end
175
+ it "適切なバージョンを指定すれば、変更前のファイルが取得できる" do
176
+ workspace.file("revision/update.txt").create("hoge")
177
+ revision = workspace.version_manager.revisions.first
178
+ workspace.file("revision/update.txt").update("fuga")
179
+ expect(workspace.file("revision/update.txt").read(revision: revision)).to eq "hoge"
180
+ end
181
+ it "不正なバージョンを指定すると、例外が発生する" do
182
+ workspace.directory("revision/invalid_revision").create
183
+ workspace.file("revision/invalid_revision/file.txt").create("hoge")
184
+ expect do
185
+ workspace.directory("revision/invalid_revision").read(revision: "invalid")
186
+ end.to raise_error StoreAgent::InvalidRevisionError
187
+ expect do
188
+ workspace.file("revision/invalid_revision/file.txt").read(revision: "invalid")
189
+ end.to raise_error StoreAgent::InvalidRevisionError
190
+ end
191
+ end
192
+ context "パーミッションの変更がバージョン管理されている" do
193
+ let :workspace do
194
+ user.workspace("#{workspace_name}_permission")
195
+ end
196
+ before do
197
+ if !workspace.exists?
198
+ workspace.create
199
+ end
200
+ end
201
+
202
+ it "パーミッションの設定後にコミットされる" do
203
+ workspace.directory("set").create
204
+ workspace.file("set/foo.txt").create
205
+ revision = workspace.version_manager.revisions.first
206
+ workspace.file("set/foo.txt").set_permission(identifier: "foo", permission_values: {write: false})
207
+ expect(workspace.version_manager.revisions.first).to_not eq revision
208
+ end
209
+ it "パーミッションの設定解除後にコミットされる" do
210
+ workspace.directory("unset").create
211
+ workspace.file("unset/bar.txt").create
212
+ revision = workspace.version_manager.revisions.first
213
+ workspace.file("unset/bar.txt").unset_permission(identifier: "foo", permission_names: ["read", "write"])
214
+ expect(workspace.version_manager.revisions.first).to_not eq revision
215
+ end
216
+ end
217
+ context "オブジェクトのコピー/移動" do
218
+ let :workspace do
219
+ user.workspace("#{workspace_name}_copy_and_move")
220
+ end
221
+ before do
222
+ if !workspace.exists?
223
+ workspace.create
224
+ workspace.directory("copy_dir").create
225
+ workspace.directory("copy_file").create
226
+ workspace.directory("copy_file_dest").create
227
+ workspace.directory("move_dir").create
228
+ workspace.directory("move_file").create
229
+ workspace.directory("move_file_dest").create
230
+ end
231
+ end
232
+
233
+ it "ファイルのコピー" do
234
+ workspace.file("copy_file/src.txt").create("copy")
235
+ workspace.file("copy_file/src.txt").copy("copy_file_dest/dest.txt")
236
+ scoped_dest_commit_id = workspace.file("copy_file_dest/dest.txt").revisions.first
237
+ workspace_last_commit_id = workspace.version_manager.revisions.first
238
+ expect(scoped_dest_commit_id).to eq workspace_last_commit_id
239
+ expect(workspace.file("copy_file/src.txt").read).to eq "copy"
240
+ expect(workspace.directory("copy_file").directory_file_count).to eq 1
241
+ expect(workspace.directory("copy_file_dest").directory_file_count).to eq 1
242
+ end
243
+ it "ファイルの移動" do
244
+ workspace.file("move_file/src.txt").create("move")
245
+ workspace.file("move_file/src.txt").move("move_file_dest/dest.txt")
246
+ scoped_src_commit_id = workspace.file("move_file/src.txt").revisions.first
247
+ scoped_dest_commit_id = workspace.file("move_file_dest/dest.txt").revisions.first
248
+ workspace_last_commit_id = workspace.version_manager.revisions.first
249
+ expect(scoped_src_commit_id).to eq workspace_last_commit_id
250
+ expect(scoped_dest_commit_id).to eq workspace_last_commit_id
251
+ expect(workspace.file("move_file_dest/dest.txt").read).to eq "move"
252
+ expect(workspace.directory("move_file").directory_file_count).to eq 0
253
+ expect(workspace.directory("move_file_dest").directory_file_count).to eq 1
254
+ end
255
+ it "ディレクトリのコピー" do
256
+ workspace.directory("copy_dir/src_dir").create
257
+ workspace.file("copy_dir/src_dir/foo.txt").create("copy")
258
+ workspace.directory("copy_dir/src_dir").copy("copy_dir/dest_dir")
259
+ scoped_dest_dir_commit_id = workspace.directory("copy_dir/dest_dir").revisions.first
260
+ scoped_dest_file_commit_id = workspace.file("copy_dir/dest_dir/foo.txt").revisions.first
261
+ workspace_last_commit_id = workspace.version_manager.revisions.first
262
+ expect(scoped_dest_dir_commit_id).to eq workspace_last_commit_id
263
+ expect(scoped_dest_file_commit_id).to eq workspace_last_commit_id
264
+ expect(workspace.file("copy_dir/dest_dir/foo.txt").read).to eq "copy"
265
+ expect(workspace.directory("copy_dir/src_dir").directory_file_count).to eq 1
266
+ expect(workspace.directory("copy_dir/dest_dir").tree_file_count).to eq 1
267
+ end
268
+ it "ディレクトリの移動" do
269
+ workspace.directory("move_dir/src_dir").create
270
+ workspace.file("move_dir/src_dir/bar.txt").create("move")
271
+ workspace.directory("move_dir/src_dir").move("move_dir/dest_dir")
272
+ scoped_src_dir_commit_id = workspace.directory("move_dir/src_dir").revisions.first
273
+ scoped_src_file_commit_id = workspace.file("move_dir/src_dir/bar.txt").revisions.first
274
+ scoped_dest_dir_commit_id = workspace.directory("move_dir/dest_dir").revisions.first
275
+ scoped_dest_file_commit_id = workspace.file("move_dir/dest_dir/bar.txt").revisions.first
276
+ workspace_last_commit_id = workspace.version_manager.revisions.first
277
+ expect(scoped_src_dir_commit_id).to eq workspace_last_commit_id
278
+ expect(scoped_src_file_commit_id).to eq workspace_last_commit_id
279
+ expect(scoped_dest_dir_commit_id).to eq workspace_last_commit_id
280
+ expect(scoped_dest_file_commit_id).to eq workspace_last_commit_id
281
+ expect(workspace.file("move_dir/dest_dir/bar.txt").read).to eq "move"
282
+ expect(workspace.directory("move_dir/src_dir").exists?).to be false
283
+ expect(workspace.directory("move_dir/dest_dir").tree_file_count).to eq 1
284
+ end
285
+ end
286
+ end