content_server 1.1.0 → 1.2.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 (137) hide show
  1. data/bin/backup_server +8 -20
  2. data/bin/content_server +8 -20
  3. data/bin/testing_memory +60 -0
  4. data/bin/testing_server +57 -0
  5. data/ext/run_in_background/mkrf_conf.rb +34 -0
  6. data/lib/content_data/content_data.rb +613 -0
  7. data/lib/content_data/version.rb +3 -0
  8. data/lib/content_data.rb +6 -0
  9. data/lib/content_server/backup_server.rb +65 -86
  10. data/lib/content_server/content_server.rb +47 -77
  11. data/lib/content_server/file_streamer.rb +27 -33
  12. data/lib/content_server/queue_copy.rb +154 -49
  13. data/lib/content_server/queue_indexer.rb +19 -11
  14. data/lib/content_server/remote_content.rb +41 -23
  15. data/lib/content_server/server.rb +91 -0
  16. data/lib/content_server/version.rb +1 -1
  17. data/lib/content_server.rb +0 -15
  18. data/lib/email/email.rb +87 -0
  19. data/lib/email/version.rb +3 -0
  20. data/lib/email.rb +4 -0
  21. data/lib/file_copy/copy.rb +68 -0
  22. data/lib/file_copy/version.rb +4 -0
  23. data/lib/file_copy.rb +4 -0
  24. data/lib/file_indexing/index_agent.rb +170 -0
  25. data/lib/file_indexing/indexer_patterns.rb +72 -0
  26. data/lib/file_indexing/version.rb +3 -0
  27. data/lib/file_indexing.rb +9 -0
  28. data/lib/file_monitoring/file_monitoring.rb +105 -0
  29. data/lib/file_monitoring/monitor_path.rb +304 -0
  30. data/lib/file_monitoring/version.rb +3 -0
  31. data/lib/file_monitoring.rb +29 -0
  32. data/lib/file_utils/file_generator/README +97 -0
  33. data/lib/file_utils/file_generator/file_generator.rb +156 -0
  34. data/lib/file_utils/file_utils.rb +260 -0
  35. data/lib/file_utils/version.rb +3 -0
  36. data/lib/file_utils.rb +4 -0
  37. data/lib/log/version.rb +3 -0
  38. data/lib/log.rb +188 -0
  39. data/lib/networking/tcp.rb +213 -0
  40. data/lib/networking/version.rb +3 -0
  41. data/lib/networking.rb +4 -0
  42. data/lib/params/version.rb +3 -0
  43. data/lib/params.rb +419 -0
  44. data/lib/process_monitoring/monitoring.rb +85 -0
  45. data/lib/process_monitoring/monitoring_info.rb +79 -0
  46. data/lib/process_monitoring/send_email.rb +40 -0
  47. data/lib/process_monitoring/thread_safe_hash.rb +77 -0
  48. data/lib/process_monitoring/version.rb +3 -0
  49. data/lib/process_monitoring.rb +6 -0
  50. data/lib/run_in_background/version.rb +3 -0
  51. data/lib/run_in_background.rb +432 -0
  52. data/lib/testing_memory/testing_memory.rb +187 -0
  53. data/lib/testing_server/testing_server.rb +236 -0
  54. data/lib/testing_server/version.rb +3 -0
  55. data/lib/testing_server.rb +12 -0
  56. data/lib/validations/index_validations.rb +106 -0
  57. data/lib/validations/version.rb +3 -0
  58. data/lib/validations.rb +4 -0
  59. data/spec/content_data/validations_spec.rb +113 -0
  60. data/spec/file_copy/copy_spec.rb +54 -0
  61. data/spec/file_indexing/index_agent_spec.rb +53 -0
  62. data/spec/networking/tcp_spec.rb +95 -0
  63. data/spec/validations/index_validations_spec.rb +77 -0
  64. data/test/content_data/content_data_test.rb +290 -0
  65. data/test/file_generator/file_generator_spec.rb +84 -0
  66. data/test/file_indexing/index_agent_test/New.txt +0 -0
  67. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/libexslt.dll +0 -0
  68. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/libxslt.dll +0 -0
  69. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/bin/xsltproc.exe +0 -0
  70. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exslt.h +102 -0
  71. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exsltconfig.h +73 -0
  72. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/exsltexports.h +140 -0
  73. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libexslt/libexslt.h +29 -0
  74. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/attributes.h +38 -0
  75. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/documents.h +93 -0
  76. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/extensions.h +262 -0
  77. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/extra.h +80 -0
  78. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/functions.h +78 -0
  79. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/imports.h +75 -0
  80. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/keys.h +53 -0
  81. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/libxslt.h +30 -0
  82. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/namespaces.h +68 -0
  83. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/numbersInternals.h +69 -0
  84. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/pattern.h +81 -0
  85. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/preproc.h +43 -0
  86. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/security.h +104 -0
  87. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/templates.h +77 -0
  88. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/transform.h +207 -0
  89. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/trio.h +216 -0
  90. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/triodef.h +220 -0
  91. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/variables.h +91 -0
  92. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/win32config.h +101 -0
  93. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xslt.h +103 -0
  94. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltInternals.h +1967 -0
  95. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltconfig.h +172 -0
  96. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltexports.h +142 -0
  97. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltlocale.h +57 -0
  98. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltutils.h +309 -0
  99. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/include/libxslt/xsltwin32config.h +105 -0
  100. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libexslt.lib +0 -0
  101. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libexslt_a.lib +0 -0
  102. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libxslt.lib +0 -0
  103. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/lib/libxslt_a.lib +0 -0
  104. data/test/file_indexing/index_agent_test/libxslt-1.1.26.win32/readme.txt +22 -0
  105. data/test/file_indexing/index_agent_test/patterns.input +3 -0
  106. data/test/file_indexing/index_agent_test.rb +51 -0
  107. data/test/file_monitoring/file_monitoring_test/conf.yml +4 -0
  108. data/test/file_monitoring/file_monitoring_test/conf_win32.yml +5 -0
  109. data/test/file_monitoring/file_monitoring_test/log +56 -0
  110. data/test/file_monitoring/file_monitoring_test.rb +0 -0
  111. data/test/file_monitoring/monitor_path_test/dir1000/test_file.1000 +1000 -0
  112. data/test/file_monitoring/monitor_path_test/dir1000/test_file.1000.0 +1000 -0
  113. data/test/file_monitoring/monitor_path_test/dir1000/test_file.1000.1 +1000 -0
  114. data/test/file_monitoring/monitor_path_test/dir1500/test_file.1500 +1500 -0
  115. data/test/file_monitoring/monitor_path_test/dir1500/test_file.1500.0 +1500 -0
  116. data/test/file_monitoring/monitor_path_test/dir1500/test_file.1500.1 +1500 -0
  117. data/test/file_monitoring/monitor_path_test/test_file.500 +500 -0
  118. data/test/file_monitoring/monitor_path_test/test_file.500.0 +500 -0
  119. data/test/file_monitoring/monitor_path_test/test_file.500.1 +500 -0
  120. data/test/file_monitoring/monitor_path_test.rb +153 -0
  121. data/test/file_utils/fileutil_mksymlink_test/dir1000/dir1500/test_file.1500 +1500 -0
  122. data/test/file_utils/fileutil_mksymlink_test/dir1000/dir1500/test_file.1500.0 +1500 -0
  123. data/test/file_utils/fileutil_mksymlink_test/dir1000/dir1500/test_file.1500.1 +1500 -0
  124. data/test/file_utils/fileutil_mksymlink_test/dir1000/test_file.1000 +1000 -0
  125. data/test/file_utils/fileutil_mksymlink_test/dir1000/test_file.1000.0 +1000 -0
  126. data/test/file_utils/fileutil_mksymlink_test/dir1000/test_file.1000.1 +1000 -0
  127. data/test/file_utils/fileutil_mksymlink_test/test_file.500 +500 -0
  128. data/test/file_utils/fileutil_mksymlink_test/test_file.500.0 +500 -0
  129. data/test/file_utils/fileutil_mksymlink_test/test_file.500.1 +500 -0
  130. data/test/file_utils/fileutil_mksymlink_test.rb +125 -0
  131. data/test/file_utils/time_modification_test.rb +132 -0
  132. data/test/params/params_spec.rb +280 -0
  133. data/test/params/params_test.rb +43 -0
  134. data/test/run_in_background/run_in_background_test.rb +122 -0
  135. data/test/run_in_background/test_app +57 -0
  136. metadata +272 -132
  137. data/lib/content_server/globals.rb +0 -10
@@ -0,0 +1,304 @@
1
+ require 'content_server/server'
2
+ require 'log'
3
+ require 'params'
4
+
5
+ module FileMonitoring
6
+ # Path monitoring.
7
+
8
+ # Enum-like structure that includes possible filesystem entities (files/directories) states:
9
+ # * <tt>NON_EXISTING</tt> - Entity that was treated during previous run, but absent currently
10
+ # * <tt>NEW</tt> - Entity that was found and added to control during this run
11
+ # * <tt>CHANGED</tt> - State was changed between two checks
12
+ # * <tt>UNCHANGED</tt> - Opposite to CHANGED
13
+ # * <tt>STABLE</tt> - Entity is in the UNCHANGED state for a defined (by user) number of iterations
14
+
15
+
16
+ class FileStatEnum
17
+ NON_EXISTING = "NON_EXISTING"
18
+ NEW = "NEW"
19
+ CHANGED = "CHANGED"
20
+ UNCHANGED = "UNCHANGED"
21
+ STABLE = "STABLE"
22
+ end
23
+
24
+ # This class holds current state of file and methods to control and report changes
25
+ class FileStat
26
+ attr_reader :cycles, :path, :stable_state, :state, :size, :modification_time
27
+
28
+ DEFAULT_STABLE_STATE = 10
29
+
30
+ @@log = nil
31
+
32
+ # Initializes new file monitoring object
33
+ # ==== Arguments:
34
+ #
35
+ # * <tt>path</tt> - File location
36
+ # * <tt>stable_state</tt> - Number of iterations to move unchanged file to stable state
37
+ def initialize(path, stable_state = DEFAULT_STABLE_STATE, content_data_cache, state)
38
+ @path ||= path
39
+ @size = nil
40
+ @creation_time = nil
41
+ @modification_time = nil
42
+ @cycles = 0 # number of iterations from the last file modification
43
+ @state = state
44
+ @stable_state = stable_state # number of iteration to move unchanged file to stable state
45
+ end
46
+
47
+ def set_output_queue(event_queue)
48
+ @event_queue = event_queue
49
+ end
50
+
51
+ # Sets a log file to report changes
52
+ # ==== Arguments:
53
+ #
54
+ # * <tt>log</tt> - already opened ruby File object
55
+ def self.set_log (log)
56
+ @@log = log
57
+ end
58
+
59
+ # Checks whether file was changed from the last iteration.
60
+ # For files, size and modification time are checked.
61
+ def monitor
62
+ file_stats = File.lstat(@path) rescue nil
63
+ new_state = nil
64
+ if file_stats == nil
65
+ new_state = FileStatEnum::NON_EXISTING
66
+ @size = nil
67
+ @creation_time = nil
68
+ @modification_time = nil
69
+ @cycles = 0
70
+ elsif @size == nil
71
+ new_state = FileStatEnum::NEW
72
+ @size = file_stats.size
73
+ @creation_time = file_stats.ctime.utc
74
+ @modification_time = file_stats.mtime.utc
75
+ @cycles = 0
76
+ elsif changed?(file_stats)
77
+ new_state = FileStatEnum::CHANGED
78
+ @size = file_stats.size
79
+ @creation_time = file_stats.ctime.utc
80
+ @modification_time = file_stats.mtime.utc
81
+ @cycles = 0
82
+ else
83
+ new_state = FileStatEnum::UNCHANGED
84
+ @cycles += 1
85
+ if @cycles >= @stable_state
86
+ new_state = FileStatEnum::STABLE
87
+ end
88
+ end
89
+
90
+ # The assignment
91
+ self.state= new_state
92
+ end
93
+
94
+ # Checks that stored file attributes are the same as file attributes taken from file system.
95
+ def changed?(file_stats)
96
+ not (file_stats.size == @size &&
97
+ file_stats.ctime.utc == @creation_time.utc &&
98
+ file_stats.mtime.utc == @modification_time.utc)
99
+ end
100
+
101
+ def set_event_queue(queue)
102
+ @event_queue = queue
103
+ end
104
+
105
+ # Sets and writes to the log a new state.
106
+ def state= (new_state)
107
+ if (@state != new_state or @state == FileStatEnum::CHANGED)
108
+ @state = new_state
109
+ if (@@log)
110
+ @@log.info(state + ": " + path)
111
+ @@log.outputters[0].flush if Params['log_flush_each_message']
112
+ end
113
+ if @event_queue and FileStatEnum::NEW != @state # NEW state is ignored in indexer
114
+ Log.debug1 "Writing to event queue [#{self.state}, #{self.path}]"
115
+ @event_queue.push([self.state, self.instance_of?(DirStat), self.path,
116
+ self.modification_time, self.size])
117
+ $process_vars.set('monitor to index queue size', @event_queue.size)
118
+ end
119
+ end
120
+ end
121
+
122
+ # Checks whether path and state are the same as of the argument
123
+ def == (other)
124
+ @path == other.path and @stable_state == other.stable_state
125
+ end
126
+
127
+ # Returns path and state of the file with indentation
128
+ def to_s (indent = 0)
129
+ (" " * indent) + path.to_s + " : " + state.to_s
130
+ end
131
+ end
132
+
133
+ # This class holds current state of directory and methods to control changes
134
+ class DirStat < FileStat
135
+ # Initializes new directory monitoring object
136
+ # ==== Arguments:
137
+ #
138
+ # * <tt>path</tt> - File location
139
+ # * <tt>stable_state</tt> - Number of iterations to move unchanged directory to stable state
140
+ def initialize(path, stable_state = DEFAULT_STABLE_STATE, content_data_cache, state)
141
+ super
142
+ @dirs = nil
143
+ @files = nil
144
+ @non_utf8_paths = {}
145
+ @content_data_cache = content_data_cache
146
+ end
147
+
148
+ # Adds directory for monitoring.
149
+ def add_dir (dir)
150
+ @dirs[dir.path] = dir
151
+ end
152
+
153
+ # Adds file for monitoring.
154
+ def add_file (file)
155
+ @files[file.path] = file
156
+ end
157
+
158
+ # Removes directory from monitoring.
159
+ def rm_dir(dir)
160
+ @dirs.delete(dir.path)
161
+ end
162
+
163
+ # Removes file from monitoring.
164
+ def rm_file(file)
165
+ @files.delete(file.path)
166
+ end
167
+
168
+ # Checks that there is a sub-folder with a given path.
169
+ def has_dir?(path)
170
+ @dirs.has_key?(path)
171
+ end
172
+
173
+ # Checks that there is a file with a given path.
174
+ def has_file?(path)
175
+ @files.has_key?(path)
176
+ end
177
+
178
+ # Returns string which contains path and state of this directory as well as it's structure.
179
+ def to_s(indent = 0)
180
+ indent_increment = 2
181
+ child_indent = indent + indent_increment
182
+ res = super
183
+ @files.each_value do |file|
184
+ res += "\n" + file.to_s(child_indent)
185
+ end if @files
186
+ @dirs.each_value do |dir|
187
+ res += "\n" + dir.to_s(child_indent)
188
+ end if @dirs
189
+ res
190
+ end
191
+
192
+ # Checks that directory structure (i.e. files and directories located directly under this directory)
193
+ # wasn't changed since the last iteration.
194
+ def monitor
195
+ was_changed = false
196
+ new_state = nil
197
+ self_stat = File.lstat(@path) rescue nil
198
+ if self_stat == nil
199
+ new_state = FileStatEnum::NON_EXISTING
200
+ @files = nil
201
+ @dirs = nil
202
+ @cycles = 0
203
+ elsif @files == nil
204
+ new_state = FileStatEnum::NEW
205
+ @files = Hash.new
206
+ @dirs = Hash.new
207
+ @cycles = 0
208
+ update_dir
209
+ elsif update_dir
210
+ new_state = FileStatEnum::CHANGED
211
+ @cycles = 0
212
+ else
213
+ new_state = FileStatEnum::UNCHANGED
214
+ @cycles += 1
215
+ if @cycles >= @stable_state
216
+ new_state = FileStatEnum::STABLE
217
+ end
218
+ end
219
+
220
+ # The assignment
221
+ self.state= new_state
222
+ end
223
+
224
+ # Updates the files and directories hashes and globs the directory for changes.
225
+ def update_dir
226
+ was_changed = false
227
+
228
+ # monitor existing and absent files
229
+ @files.each_value do |file|
230
+ file.monitor
231
+
232
+ if file.state == FileStatEnum::NON_EXISTING
233
+ was_changed = true
234
+ rm_file(file)
235
+ end
236
+ end
237
+
238
+ @dirs.each_value do |dir|
239
+ dir.monitor
240
+
241
+ if dir.state == FileStatEnum::NON_EXISTING
242
+ was_changed = true
243
+ rm_dir(dir)
244
+ end
245
+ end
246
+
247
+ was_changed = was_changed || glob_me
248
+
249
+ return was_changed
250
+ end
251
+
252
+ # Globs the directory for new files and directories
253
+ def glob_me
254
+ was_changed = false
255
+ files = Dir.glob(path + "/*")
256
+
257
+ # add and monitor new files and directories
258
+ files.each do |file|
259
+ # keep only files with names in UTF-8
260
+ next if @non_utf8_paths[file]
261
+ check_utf_8_encoding_file = file.clone
262
+ unless check_utf_8_encoding_file.force_encoding("UTF-8").valid_encoding?
263
+ Log.warning("Non UTF-8 file name '#{check_utf_8_encoding_file}', skipping.")
264
+ @non_utf8_paths[file]=true
265
+ next
266
+ end
267
+ file_stat = File.lstat(file) rescue nil
268
+ if (file_stat.directory?)
269
+ unless (has_dir?(file)) # new directory
270
+ # change state only for existing directories
271
+ # newly added directories have to remain with NEW state
272
+ was_changed = true
273
+ ds = DirStat.new(file, self.stable_state, @content_data_cache, FileStatEnum::NON_EXISTING)
274
+ ds.set_event_queue(@event_queue) unless @event_queue.nil?
275
+ ds.monitor
276
+ add_dir(ds)
277
+ end
278
+ else # it is a file
279
+ unless(has_file?(file)) # new file
280
+ # change state only for existing directories
281
+ # newly added directories have to remain with NEW state
282
+ was_changed = true
283
+ # check if file exist in content data cache - set state to STABLE
284
+ file_state = FileStatEnum::NON_EXISTING
285
+ if !@content_data_cache.nil? && @content_data_cache.include?(file)
286
+ file_state = FileStatEnum::STABLE
287
+ end
288
+ fs = FileStat.new(file, self.stable_state, @content_data_cache, file_state)
289
+
290
+ fs.set_event_queue(@event_queue) unless @event_queue.nil?
291
+ fs.monitor
292
+ add_file(fs)
293
+ end
294
+ end
295
+ end
296
+
297
+ return was_changed
298
+ end
299
+
300
+ protected :add_dir, :add_file, :rm_dir, :rm_file, :update_dir, :glob_me
301
+ end
302
+
303
+ end
304
+
@@ -0,0 +1,3 @@
1
+ module FileMonitoring
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,29 @@
1
+ require 'file_monitoring/file_monitoring'
2
+
3
+ # Daemon for monitoring directories for changes.
4
+ # Paths are checked for changes per user-defined period of time.
5
+ #
6
+ # Directory defined changed when:
7
+ # 1. Directory structure changed, i.e. sub-directories or files were added/removed
8
+ # 2. One of the files located in the directory or one of its sub-directories was changed
9
+ # 3. One of sub-directories changed (see 1. and 2. above)
10
+ #
11
+ # File monitoring controled by following configuration parameters:
12
+ # * <tt>default_monitoring_log_path</tt> - holds path of file monitoring log.
13
+ # This log containd track of changes found during monitoring
14
+ # * <tt>monitoring_paths</tt> - path and file monitoring configuration data
15
+ # regarding these paths.
16
+
17
+ module FileMonitoring
18
+ Params.path('default_monitoring_log_path', '~/.bbfs/log/file_monitoring.log',
19
+ 'Default path for file monitoring log file. ' \
20
+ 'This log containd track of changes found during monitoring')
21
+ Params.complex('monitoring_paths', [], 'Array of Hashes with 3 fields: ' \
22
+ 'path, scan_period and stable_state.')
23
+
24
+ # @see FileMonitoring#monitor_files
25
+ def monitor_files
26
+ fm = FileMonitoring.new
27
+ fm.monitor_files
28
+ end
29
+ end
@@ -0,0 +1,97 @@
1
+ File Generator utility
2
+ ------------------------------------------------------------------
3
+ A. Short program description:
4
+ Generates files and folders with random content with random file size according to
5
+ the given FileGenerator Parameters.
6
+ The parameters can be provided by two ways. One way is by YML file. Second way is
7
+ by passing parameters to application trought command line.
8
+ The two ways and meaning of parameters described in next sections.
9
+
10
+ B. Instalation of application and it dependencies:
11
+ 1. The File Generator utility is integrated to general file utility.
12
+ You have to install file_utils and log
13
+ Install file_utils as follow:
14
+ bbfs> gem build file_utils.gemspec
15
+ after run this you will get next message: "Successfully built RubyGem..."
16
+ and run:
17
+ bbfs> gem install file_utils-0.0.1.gem
18
+ after run this you will get next message:
19
+ "Successfully installed file_utils-0.0.1..."
20
+
21
+ 2. The File Generation Util is depend on log gem. Install log gem as follow:
22
+ bbfs> gem build log.gemspec
23
+ after run this you will get next message: "Successfully built RubyGem..."
24
+ run:
25
+ bbfs> gem install log-0.0.1.gem
26
+ and get "Successfully installed log-0.0.1..."
27
+
28
+ C. How to run.
29
+ 1. Create YML configuration file and locate it in file system. The path where the
30
+ YML file is located must be provided by --conf_file parameter that passed to
31
+ program in command line.
32
+ 2. Run the program by
33
+ bbfs> ruby -Ilib bin/file_utils --command=generate_files --conf_file=~/.bbfs/conf/file_generator.yml
34
+ 3. In order to see all parameters that can be provided to application run next:
35
+ bbfs> ruby -Ilib bin/file_utils --print_params_to_stdout=true
36
+ 4. In order to get help run: bbfs> ruby -Ilib bin/file_utils --help
37
+
38
+ D. Desription of YML file
39
+ The parameters of YML file is divided to two relevant group:
40
+ "Location and naming", "Processing"
41
+
42
+ ********************************Location and naming*******************************
43
+ target_path - Represents the root path where directories and files will be
44
+ generated.
45
+ dir_name_prefix - Represents the directory name template. Name of created
46
+ directories will be dir_name_prefix_xxx. where xxx is random
47
+ characters
48
+ file_name_prefix - Represents the file name template for generated file. Name of
49
+ created files will be dir_name_prefix_xxx. where xxx is random
50
+ characters
51
+
52
+ *******************************************Processing**********************************************
53
+ total_created_directories - Represents the total created directories. Use any
54
+ negative value or zero for Infinity. Not relevant if
55
+ random calculation is triggered.
56
+ is_tot_files_in_dir_random - Indicates that total files in a directory will be
57
+ calculated randomly. If false then value will be
58
+ taken from parameter:'total_files_in_dir'.
59
+ Also lower\upper_limit_4_files_in_dir parameters will
60
+ not be used.
61
+ lower_limit_4_files_in_dir - Represents the Lower limit for total files in
62
+ directory for random calculation. Active only if
63
+ parameter:'is_tot_files_in_dir_random' is true.
64
+ upper_limit_4_files_in_dir - Represents the Upper limit for total files in
65
+ directory for random calculation. Active only if
66
+ parameter:'is_tot_files_in_dir_random' is true.
67
+ total_files_in_dir - Represents the total files in directory. Use any
68
+ negative value or zero for Infinity. Active only if
69
+ parameter:'is_tot_files_in_dir_random' is false.
70
+ is_use_random_size - Indicates that file size will be calculated randomly.
71
+ If false then value will be taken from
72
+ parameter:'file_size_in_mb'. Also next 2 parameters
73
+ will not be used.
74
+ upper_size_in_mb - Represents the upper limit file size in MB for random
75
+ size calculation.
76
+ Active only if parameter:'is_use_random_size' is
77
+ true.
78
+ down_size_in_mb - Represents the Lower limit file size in MB for random
79
+ size calculation. Active only if
80
+ parameter:'is_use_random_size' is true.
81
+ file_size_in_mb - Represents the file size in MB. Not relevant if
82
+ random calculation is triggered. Active only if
83
+ parameter:'is_use_random_size' is false.
84
+ sleep_time_in_seconds - Represent delay between two close cycles of
85
+ processing. In each cycle of processing
86
+ file\s and\or folder\s created.
87
+
88
+ Example of using parameter in yml document is in line below:
89
+ target_path: home/user_name/.bbfs/test_files
90
+
91
+ Note: you can override parameters given in YML file by providing the parameter
92
+ trough command line.
93
+
94
+
95
+
96
+
97
+
@@ -0,0 +1,156 @@
1
+ # Author: Slava Pasechnik (slavapas13@gmail.com)
2
+ # Run from bbfs> file_utils generate_files
3
+
4
+ require 'digest'
5
+ require 'fileutils'
6
+ require 'params'
7
+ require 'yaml'
8
+
9
+ require 'log'
10
+
11
+ module FileGenerator
12
+ Params.path('target_path', '~/.bbfs/test_files', 'Represents the target path for files generation')
13
+ Params.boolean('is_clear_target_path', false, 'Should files and directories already presented in target path be removed')
14
+ Params.string('file_name_prefix', 'auto_generated_file_4_backup_server',
15
+ 'Represents the file name template for generated file')
16
+ Params.string('dir_name_prefix', 'test_dir_4_backup_server',
17
+ 'Represents the directory name template for generated file')
18
+ Params.integer('file_size_in_bytes', 500,
19
+ 'Represents the required file size in MB. Not relevant if random calculation is triggered')
20
+ Params.integer('total_created_directories', -1,
21
+ 'Represents the total created directories. Use any negative value or zero for Infinity.
22
+ Not relevant if random calculation is triggered')
23
+ Params.integer('max_total_files', 0, 'Maximum number of files to generate, 0 for no limit.')
24
+ Params.integer('total_files_in_dir', 10,
25
+ 'Represents the total files in directory. Use any negative value or zero for Infinity')
26
+ Params.float('sleep_time_in_seconds', 10, 'Represents the sleeping time for generation files')
27
+ Params.float('upper_size_in_bytes', 500, 'Represents the upper limit file size in MB for random size calculation')
28
+ Params.float('down_size_in_bytes', 50, 'Represents the Lower limit file size in MB for random size calculation')
29
+ Params.integer('lower_limit_4_files_in_dir', 10,
30
+ 'Represents the Lower limit for total files in directory for random calculation')
31
+ Params.integer('upper_limit_4_files_in_dir', 20,
32
+ 'Represents the Upper limit for total files in directory for random calculation')
33
+ Params.boolean('is_tot_files_in_dir_random', true,
34
+ 'Indicates that total files in a directory will be calculated randomly.')
35
+ Params.boolean('is_use_random_size', true, 'Indicates that file size will be calculated randomly.')
36
+
37
+ #Generates files with random content with random file size according to the given Params
38
+ class FileGenerator
39
+ attr_reader :one_bytes_string
40
+ FILE_EXT = 'txt'
41
+
42
+ #Gets one MB string
43
+ def one_bytes_string
44
+ @one_bytes_string ||= prepare_one_bytes_string
45
+ end
46
+
47
+ #Gets the some random string
48
+ def get_small_rand_unique_str
49
+ rand(36**8).to_s(36)
50
+ end
51
+
52
+ #Gets the unique name according to current time and random string
53
+ def get_unique_name
54
+ "#{Time.new.to_i}_#{get_small_rand_unique_str}"
55
+ end
56
+
57
+ #Gets the random letter
58
+ def get_random_letter
59
+ (rand(122-97) + 97).chr
60
+ end
61
+
62
+ #Gets the new directory name
63
+ def get_new_directory_name
64
+ "#{Params['dir_name_prefix']}_#{get_unique_name}"
65
+ end
66
+
67
+ #Gets the new file name
68
+ def get_new_file_name
69
+ "#{Params['file_name_prefix']}_#{get_unique_name}.#{FILE_EXT}"
70
+ end
71
+
72
+ #Gets the required file size im MB
73
+ def get_file_bytes_size
74
+ if Params['is_use_random_size']
75
+ rand(Params['upper_size_in_bytes'] - Params['down_size_in_bytes']) +
76
+ Params['down_size_in_bytes']
77
+ else
78
+ Params['file_size_in_bytes']
79
+ end
80
+ end
81
+
82
+ #Generates one MB string with random content
83
+ def prepare_one_bytes_string
84
+ get_random_letter
85
+ end
86
+
87
+ #Determines whether to generate new directory or not
88
+ def is_generate_dir(dir_counter, total_file_counter)
89
+ if Params['max_total_files'] > 0 && total_file_counter > Params['max_total_files']
90
+ return false
91
+ end
92
+
93
+ if Params['total_created_directories'] < 1 || #Any negative value or zero will be indication for Infinity
94
+ dir_counter < Params['total_created_directories'] then
95
+ return true
96
+ else
97
+ return false
98
+ end
99
+ end
100
+
101
+ #Determines whether to generate new file or not
102
+ def is_generate_file(file_counter, total_file_counter)
103
+ if Params['max_total_files'] > 0 && total_file_counter > Params['max_total_files']
104
+ return false
105
+ end
106
+
107
+ total_files_in_dir = Params['total_files_in_dir']
108
+ if file_counter == 0 && Params['is_tot_files_in_dir_random'] then
109
+ total_files_in_dir =
110
+ rand(Params['upper_limit_4_files_in_dir'] -
111
+ Params['lower_limit_4_files_in_dir']) +
112
+ Params['lower_limit_4_files_in_dir']
113
+ end
114
+
115
+ #When total_files_in_dir < 1 it will be treated as unlimited files creation in directory
116
+ if total_files_in_dir < 1 ||
117
+ file_counter < total_files_in_dir then
118
+ return true
119
+ else
120
+ return false
121
+ end
122
+ end
123
+
124
+ #Generates files with random content with random file size according to the given Params
125
+ def run
126
+ dir_counter = 0
127
+ total_file_count = 0
128
+ if Params['is_clear_target_path']
129
+ target_path_all_regexp = File.expand_path(File.join(Params['target_path'], '*'))
130
+ Dir[target_path_all_regexp].each {|file| FileUtils.rm_rf file}
131
+ end
132
+ while is_generate_dir dir_counter, total_file_count
133
+ new_dir_name = File.expand_path(File.join Params['target_path'], get_new_directory_name)
134
+ ::FileUtils.mkdir_p new_dir_name unless File.directory?(new_dir_name)
135
+ dir_counter += 1
136
+ file_counter = 0
137
+
138
+ while is_generate_file file_counter, total_file_count
139
+ new_file_name = get_new_file_name
140
+ File.open(File.join(new_dir_name, new_file_name), "w") do |f|
141
+ get_file_bytes_size.to_i.times { f.write(get_random_letter) }
142
+ end
143
+ file_counter += 1
144
+ total_file_count += 1
145
+
146
+ sleep Params['sleep_time_in_seconds'] if Params['sleep_time_in_seconds'] > 0
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end # module FileGenerator
152
+
153
+
154
+
155
+
156
+