virtfs-camcorderfs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +78 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/virtfs-camcorderfs.rb +1 -0
- data/lib/virtfs/camcorderfs.rb +13 -0
- data/lib/virtfs/camcorderfs/cc_delegate.rb +18 -0
- data/lib/virtfs/camcorderfs/cc_delegate/dir_class_methods.rb +51 -0
- data/lib/virtfs/camcorderfs/cc_delegate/dir_instance_methods.rb +20 -0
- data/lib/virtfs/camcorderfs/cc_delegate/file_class_methods.rb +188 -0
- data/lib/virtfs/camcorderfs/cc_delegate/file_instance_methods.rb +145 -0
- data/lib/virtfs/camcorderfs/dir.rb +37 -0
- data/lib/virtfs/camcorderfs/file.rb +157 -0
- data/lib/virtfs/camcorderfs/fs.rb +106 -0
- data/lib/virtfs/camcorderfs/fs/dir_class_methods.rb +38 -0
- data/lib/virtfs/camcorderfs/fs/dir_instance_methods.rb +20 -0
- data/lib/virtfs/camcorderfs/fs/file_class_methods.rb +179 -0
- data/lib/virtfs/camcorderfs/fs/file_instance_methods.rb +144 -0
- data/lib/virtfs/camcorderfs/real_dir.rb +27 -0
- data/lib/virtfs/camcorderfs/real_file.rb +27 -0
- data/lib/virtfs/camcorderfs/version.rb +5 -0
- data/virtfs-camcorderfs.gemspec +32 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: be77d1b97712695378353a6e7647dfce34c16305
|
4
|
+
data.tar.gz: 4e77cf4c7197d43e9b3b988aaa1192e655b2488d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0dd365a9cd7eaa04a64703394bf45c9b44192ce8748e1e26cf0d7cadbacb2e42b01d625f6ad825194437b136cbceac1d1196b61b4793f9b18aae6205c4156b28
|
7
|
+
data.tar.gz: df2bd25adeb9af45c9356b76772d52fe461d59674493ccbb9ded91b9c3b4fd25dcd37d112f679a91908e4f9b4431eaaaeca32777ffd2383dae75ba4566fc3672
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Richard Oliveri
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# VirtFS/CamcorderFS
|
2
|
+
|
3
|
+
A pseudo filesystem plugin for the **VirtFS** infrastructure, that provides the ability to record/playback all filesystem activity that is performed through a given mount point.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'virtfs-camcorderfs'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install virtfs-camcorderfs
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
The **virtfs-camcorderfs** enables the user to _mount_ a given directory of the native filesystem on a virtual mount point within the **virtfs** infrastructure. Once mounted, all filesystem operations performed through the virtual mount point are recorded or played back as follows:
|
24
|
+
|
25
|
+
When a `VirtFS::CamcorderFS::FS` instance is instantiated, it is passed the loaction of the recording (cassette) file to be used.
|
26
|
+
|
27
|
+
* When the cassette file doesn't exist, the `VirtFS::CamcorderFS::FS` instance is in **record** mode. Once mounted, the instance will **record** all filesystem activity performed through the virtual mount point.
|
28
|
+
|
29
|
+
* When the cassette file does exist `VirtFS::CamcorderFS::FS` instance is in **playback** mode. Once mounted, the instance will **playback** all filesystem activity recorded to the cassette file, bypassing native file system access.
|
30
|
+
|
31
|
+
This capability is very useful in developing automated tests that rely on specific aspects of the filesystem that may not be available in the automated test environment (like Travis).
|
32
|
+
|
33
|
+
For example, say your tests require access to an NFS share or a block special file. Chances are, the share or special file in question will not be accessible in the Travis environment. The **virtfs-camcorderfs** plugin provides a solution to this problem similar to the solutions provided by the [**VCR**](https://github.com/vcr/vcr) and [**camcorder**](https://github.com/ghempton/camcorder) gems. In fact, as the name implies, **virtfs-camcorderfs** uses the **camcorder** gem to perform record/playback.
|
34
|
+
|
35
|
+
So, the tests are first run in the base test environemnt, the cassette files are recorded and committed along with the tests. When the tests are run within the Travis environemnt, the filesystem interactions are played back from the cassette files, eliminating the need to access the aspects of the filesystem that are not available in the Travis environemnt.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require "virtfs-nativefs-thick"
|
39
|
+
require "virtfs-camcorderfs"
|
40
|
+
|
41
|
+
# Instantiate an instance of the native filesystem.
|
42
|
+
native_fs = VirtFS::NativeFS::Thick.new
|
43
|
+
|
44
|
+
# Mount the native filesystem on root "/"
|
45
|
+
VirtFS.mount(native_fs, "/")
|
46
|
+
|
47
|
+
# Instantiate an instance of CamcorderFS, specifying the cassette file.
|
48
|
+
cc_fs = VirtFS::CamcorderFS::FS.new(@recording_file)
|
49
|
+
|
50
|
+
#
|
51
|
+
# Mount /dev of the native filesystem on /dev of
|
52
|
+
# the VirtFS namespace, through CamcorderFS.
|
53
|
+
#
|
54
|
+
cc_fs.root = "/dev"
|
55
|
+
VirtFS.mount(cc_fs, "/dev")
|
56
|
+
|
57
|
+
VirtFS.with do
|
58
|
+
#
|
59
|
+
# Access files under /dev as needed.
|
60
|
+
# Interactions are recorded/played back.
|
61
|
+
#
|
62
|
+
end
|
63
|
+
|
64
|
+
VirtFS.umount("/dev")
|
65
|
+
```
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
1. Fork it
|
70
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
71
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
72
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
73
|
+
5. Create new Pull Request
|
74
|
+
|
75
|
+
## License
|
76
|
+
|
77
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
78
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "comcorderfs"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "virtfs/camcorderfs"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'camcorder'
|
3
|
+
|
4
|
+
require_relative "camcorderfs/version"
|
5
|
+
|
6
|
+
require_relative "camcorderfs/real_dir"
|
7
|
+
require_relative "camcorderfs/real_file"
|
8
|
+
|
9
|
+
require_relative "camcorderfs/cc_delegate"
|
10
|
+
require_relative "camcorderfs/fs"
|
11
|
+
|
12
|
+
require_relative "camcorderfs/dir"
|
13
|
+
require_relative "camcorderfs/file"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'cc_delegate/dir_class_methods'
|
2
|
+
require_relative 'cc_delegate/dir_instance_methods'
|
3
|
+
require_relative 'cc_delegate/file_class_methods'
|
4
|
+
require_relative 'cc_delegate/file_instance_methods'
|
5
|
+
|
6
|
+
module VirtFS::CamcorderFS # rubocop:disable Style/ClassAndModuleChildren
|
7
|
+
class CcDelegate
|
8
|
+
include DirClassMethods
|
9
|
+
include DirInstanceMethods
|
10
|
+
include FileClassMethods
|
11
|
+
include FileInstanceMethods
|
12
|
+
|
13
|
+
def instance_call(method, instance_handle, *args)
|
14
|
+
instance_handle.send(method, *args)
|
15
|
+
end
|
16
|
+
private :instance_call
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# Dir class methods - are instance methods of filesystem instance.
|
3
|
+
#
|
4
|
+
module VirtFS::CamcorderFS # rubocop:disable Style/ClassAndModuleChildren
|
5
|
+
#
|
6
|
+
# Directory class methods - called by CamcorderFS::FS.
|
7
|
+
# Methods are wraped in delegate class for camcorder interposition.
|
8
|
+
#
|
9
|
+
class CcDelegate
|
10
|
+
module DirClassMethods
|
11
|
+
def dir_chdir(_p)
|
12
|
+
0 # needed for side effects.
|
13
|
+
end
|
14
|
+
|
15
|
+
def dir_delete(p)
|
16
|
+
VfsRealDir.delete(p)
|
17
|
+
end
|
18
|
+
|
19
|
+
def dir_entries(p)
|
20
|
+
VfsRealDir.entries(p)
|
21
|
+
end
|
22
|
+
|
23
|
+
def dir_exist?(p)
|
24
|
+
VfsRealDir.exist?(p)
|
25
|
+
end
|
26
|
+
|
27
|
+
def dir_foreach(p)
|
28
|
+
VfsRealDir.foreach(p).to_a
|
29
|
+
end
|
30
|
+
|
31
|
+
def dir_mkdir(p, permissions)
|
32
|
+
VfsRealDir.mkdir(p, permissions)
|
33
|
+
end
|
34
|
+
|
35
|
+
def dir_new(fs_rel_path, hash_args, _open_path, cwd)
|
36
|
+
owd = VfsRealDir.getwd
|
37
|
+
begin
|
38
|
+
VfsRealDir.chdir(cwd)
|
39
|
+
return marshallable_dir(RealDir.new(fs_rel_path, hash_args))
|
40
|
+
ensure
|
41
|
+
VfsRealDir.chdir(owd)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def marshallable_dir(dir)
|
46
|
+
dir.instance_variable_set(:@__cc_id, dir.object_id)
|
47
|
+
dir
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module VirtFS::CamcorderFS # rubocop:disable Style/ClassAndModuleChildren
|
2
|
+
#
|
3
|
+
# Directory instance methods - called by CamcorderFS::Dir instances.
|
4
|
+
# Methods are wraped in delegate class for camcorder interposition.
|
5
|
+
#
|
6
|
+
class CcDelegate
|
7
|
+
module DirInstanceMethods
|
8
|
+
#
|
9
|
+
# Dir instance methods - implementation.
|
10
|
+
#
|
11
|
+
def dir_i_close(instance_handle)
|
12
|
+
instance_call(:close, instance_handle)
|
13
|
+
end
|
14
|
+
|
15
|
+
def dir_i_each(instance_handle)
|
16
|
+
instance_call(:each, instance_handle).to_a
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#
|
2
|
+
# File class methods - are instance methods of filesystem instance.
|
3
|
+
#
|
4
|
+
module VirtFS::CamcorderFS # rubocop:disable Style/ClassAndModuleChildren
|
5
|
+
#
|
6
|
+
# File class methods - called by CamcorderFS::FS.
|
7
|
+
# Methods are wraped in delegate class for camcorder interposition.
|
8
|
+
#
|
9
|
+
class CcDelegate
|
10
|
+
module FileClassMethods
|
11
|
+
def file_atime(p)
|
12
|
+
VfsRealFile.atime(p)
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_blockdev?(p)
|
16
|
+
VfsRealFile.blockdev?(p)
|
17
|
+
end
|
18
|
+
|
19
|
+
def file_chardev?(p)
|
20
|
+
VfsRealFile.chardev?(p)
|
21
|
+
end
|
22
|
+
|
23
|
+
def file_chmod(permission, p)
|
24
|
+
VfsRealFile.chmod(permission, p)
|
25
|
+
end
|
26
|
+
|
27
|
+
def file_chown(owner, group, p)
|
28
|
+
VfsRealFile.chown(owner, group, p)
|
29
|
+
end
|
30
|
+
|
31
|
+
def file_ctime(p)
|
32
|
+
VfsRealFile.ctime(p)
|
33
|
+
end
|
34
|
+
|
35
|
+
def file_delete(p)
|
36
|
+
VfsRealFile.delete(p)
|
37
|
+
end
|
38
|
+
|
39
|
+
def file_directory?(p)
|
40
|
+
VfsRealFile.directory?(p)
|
41
|
+
end
|
42
|
+
|
43
|
+
def file_executable?(p)
|
44
|
+
VfsRealFile.executable?(p)
|
45
|
+
end
|
46
|
+
|
47
|
+
def file_executable_real?(p)
|
48
|
+
VfsRealFile.executable_real?(p)
|
49
|
+
end
|
50
|
+
|
51
|
+
def file_exist?(p)
|
52
|
+
VfsRealFile.exist?(p)
|
53
|
+
end
|
54
|
+
|
55
|
+
def file_file?(p)
|
56
|
+
VfsRealFile.file?(p)
|
57
|
+
end
|
58
|
+
|
59
|
+
def file_ftype(p)
|
60
|
+
VfsRealFile.ftype(p)
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_grpowned?(p)
|
64
|
+
VfsRealFile.grpowned?(p)
|
65
|
+
end
|
66
|
+
|
67
|
+
def file_identical?(p1, p2)
|
68
|
+
VfsRealFile.identical?(p1, p2)
|
69
|
+
end
|
70
|
+
|
71
|
+
def file_lchmod(permission, p)
|
72
|
+
VfsRealFile.lchmod(permission, p)
|
73
|
+
end
|
74
|
+
|
75
|
+
def file_lchown(owner, group, p)
|
76
|
+
VfsRealFile.lchown(owner, group, p)
|
77
|
+
end
|
78
|
+
|
79
|
+
def file_link(p1, p2)
|
80
|
+
VfsRealFile.link(p1, p2)
|
81
|
+
end
|
82
|
+
|
83
|
+
def file_lstat(p)
|
84
|
+
VirtFS::Stat.new(VfsRealFile.lstat(p))
|
85
|
+
end
|
86
|
+
|
87
|
+
def file_mtime(p)
|
88
|
+
VfsRealFile.mtime(p)
|
89
|
+
end
|
90
|
+
|
91
|
+
def file_owned?(p)
|
92
|
+
VfsRealFile.owned?(p)
|
93
|
+
end
|
94
|
+
|
95
|
+
def file_pipe?(p)
|
96
|
+
VfsRealFile.pipe?(p)
|
97
|
+
end
|
98
|
+
|
99
|
+
def file_readable?(p)
|
100
|
+
VfsRealFile.readable?(p)
|
101
|
+
end
|
102
|
+
|
103
|
+
def file_readable_real?(p)
|
104
|
+
VfsRealFile.readable_real?(p)
|
105
|
+
end
|
106
|
+
|
107
|
+
def file_readlink(p)
|
108
|
+
VfsRealFile.readlink(p)
|
109
|
+
end
|
110
|
+
|
111
|
+
def file_rename(p1, p2)
|
112
|
+
VfsRealFile.rename(p1, p2)
|
113
|
+
end
|
114
|
+
|
115
|
+
def file_setgid?(p)
|
116
|
+
VfsRealFile.setgid?(p)
|
117
|
+
end
|
118
|
+
|
119
|
+
def file_setuid?(p)
|
120
|
+
VfsRealFile.setuid?(p)
|
121
|
+
end
|
122
|
+
|
123
|
+
def file_size(p)
|
124
|
+
VfsRealFile.size(p)
|
125
|
+
end
|
126
|
+
|
127
|
+
def file_socket?(p)
|
128
|
+
VfsRealFile.socket?(p)
|
129
|
+
end
|
130
|
+
|
131
|
+
def file_stat(p)
|
132
|
+
VirtFS::Stat.new(VfsRealFile.stat(p))
|
133
|
+
end
|
134
|
+
|
135
|
+
def file_sticky?(p)
|
136
|
+
VfsRealFile.sticky?(p)
|
137
|
+
end
|
138
|
+
|
139
|
+
def file_symlink(oname, p)
|
140
|
+
VfsRealFile.symlink(oname, p)
|
141
|
+
end
|
142
|
+
|
143
|
+
def file_symlink?(p)
|
144
|
+
VfsRealFile.symlink?(p)
|
145
|
+
end
|
146
|
+
|
147
|
+
def file_truncate(p, len)
|
148
|
+
VfsRealFile.truncate(p, len)
|
149
|
+
end
|
150
|
+
|
151
|
+
def file_utime(atime, mtime, p)
|
152
|
+
VfsRealFile.utime(atime, mtime, p)
|
153
|
+
end
|
154
|
+
|
155
|
+
def file_world_readable?(p)
|
156
|
+
VfsRealFile.world_readable?(p)
|
157
|
+
end
|
158
|
+
|
159
|
+
def file_world_writable?(p)
|
160
|
+
VfsRealFile.world_writable?(p)
|
161
|
+
end
|
162
|
+
|
163
|
+
def file_writable?(p)
|
164
|
+
VfsRealFile.writable?(p)
|
165
|
+
end
|
166
|
+
|
167
|
+
def file_writable_real?(p)
|
168
|
+
VfsRealFile.writable_real?(p)
|
169
|
+
end
|
170
|
+
|
171
|
+
def file_new(fs_rel_path, parsed_args, _open_path, cwd)
|
172
|
+
owd = VfsRealDir.getwd
|
173
|
+
begin
|
174
|
+
VfsRealDir.chdir(cwd)
|
175
|
+
fobj = RealFile.new(fs_rel_path, parsed_args.mode_bits & ~VfsRealFile::APPEND, :binmode => true)
|
176
|
+
return marshallable_file(fobj)
|
177
|
+
ensure
|
178
|
+
VfsRealDir.chdir(owd)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def marshallable_file(file)
|
183
|
+
file.instance_variable_set(:@__cc_id, file.object_id)
|
184
|
+
file
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|