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,132 @@
1
+ require 'fileutils'
2
+ require 'time'
3
+ require 'test/unit'
4
+
5
+ require 'content_data'
6
+ require 'file_indexing'
7
+ require 'file_utils'
8
+ require 'log'
9
+ require 'params'
10
+
11
+ module FileUtils
12
+ def FileUtils.parse_time time_str
13
+ return nil unless time_str.instance_of? String
14
+ seconds_from_epoch = Integer time_str # Not using to_i here because it does not check string is integer.
15
+ time = Time.at seconds_from_epoch
16
+ end
17
+
18
+ module Test
19
+ class TestTimeModification < ::Test::Unit::TestCase
20
+ # directory where tested files will be placed: __FILE__/time_modification_test
21
+ RESOURCES_DIR = File.expand_path(File.dirname(__FILE__) + "/time_modification_test")
22
+ # minimal time that will be inserted in content
23
+ MOD_TIME_CONTENTS = FileUtils.parse_time("1306527039")
24
+ # minimal time that will be inserted in instance
25
+ MOD_TIME_INSTANCES = FileUtils.parse_time("1306527039")
26
+ #time_str = "2002/02/01 02:23:59.000"
27
+ #MOD_TIME_INSTANCES = Time.strftime( time_str, '%Y/%m/%d %H:%M:%S.%L' )
28
+ DEVICE_NAME = "hd1"
29
+
30
+ @input_db
31
+ @mod_content_checksum = nil # checksum of the content that was manually modified
32
+ @mod_instance_checksum = nil # checksum of the instance that was manually modified
33
+
34
+ def setup
35
+ sizes = [500, 1000, 1500]
36
+ numb_of_copies = 2
37
+ test_file_name = "test_file"
38
+
39
+ Dir.mkdir(RESOURCES_DIR) unless (File.exists?(RESOURCES_DIR))
40
+ raise "Can't create writable working directory: #{RESOURCES_DIR}" unless \
41
+ (File.exists?(RESOURCES_DIR) and File.writable?(RESOURCES_DIR))
42
+ # prepare files for testing
43
+ sizes.each do |size|
44
+ file_path = "#{RESOURCES_DIR}/#{test_file_name}.#{size}"
45
+ file = File.open(file_path, "w", 0777) do |file|
46
+ content = Array.new
47
+ size.times do |i|
48
+ content.push(sprintf("%5d ", i))
49
+ end
50
+ file.puts(content)
51
+ end
52
+ File.utime File.atime(file_path), MOD_TIME_CONTENTS, file_path
53
+ numb_of_copies.times do |i|
54
+ ::FileUtils.cp(file_path, "#{file_path}.#{i}")
55
+ end
56
+ end
57
+
58
+ indexer = FileIndexing::IndexAgent.new
59
+ patterns = FileIndexing::IndexerPatterns.new
60
+ patterns.add_pattern(RESOURCES_DIR + '\*')
61
+ indexer.index(patterns)
62
+
63
+ @input_db = indexer.indexed_content
64
+ end
65
+
66
+ # This test compares two ways of ruby + OS to get mtime (modification file) of a file.
67
+ # We can see that in Windows there is a difference.
68
+ def test_local_os
69
+ Dir.mkdir(RESOURCES_DIR) unless (File.exists?(RESOURCES_DIR))
70
+ file_path = "#{RESOURCES_DIR}/local_os_test.test"
71
+ file = File.open(file_path, "w", 0777) do |file|
72
+ file.puts("kuku")
73
+ end
74
+ file_stats = File.stat(file_path)
75
+ Log.info "MOD_TIME_CONTENTS: #{MOD_TIME_CONTENTS}."
76
+ Log.info "MOD_TIME_CONTENTS: #{MOD_TIME_CONTENTS.to_i}."
77
+ Log.info "file_stat.mtime: #{file_stats.mtime}."
78
+ Log.info "file_stat.mtime: #{file_stats.mtime.to_i}."
79
+ Log.info "File.mtime: #{File.mtime(file_path)}."
80
+ Log.info "File.mtime: #{File.mtime(file_path).to_i}."
81
+ File.utime File.atime(file_path), MOD_TIME_CONTENTS, file_path
82
+ file_stats = File.stat(file_path)
83
+ Log.info "file_stat.mtime: #{file_stats.mtime}."
84
+ Log.info "file_stat.mtime: #{file_stats.mtime.to_i}."
85
+ Log.info "File.mtime: #{File.mtime(file_path)}."
86
+ Log.info "File.mtime: #{File.mtime(file_path).to_i}."
87
+
88
+ file_mtime = nil
89
+ file = File.open(file_path, "r") do |file|
90
+ Log.info "file.open.mtime = #{file.mtime}"
91
+ Log.info "file.open.mtime = #{file.mtime.to_i}"
92
+ file_mtime = file.mtime
93
+ end
94
+
95
+ assert_equal(MOD_TIME_CONTENTS, file_mtime)
96
+
97
+ # !!! This fails on windows with different timezone
98
+ # assert_equal(MOD_TIME_CONTENTS, file_stats.mtime)
99
+ end
100
+
101
+ def test_modify
102
+ # modified ContentData. Test files also were modified.
103
+ mod_db = FileUtils.unify_time(@input_db)
104
+
105
+ Log.info "==============="
106
+ Log.info @input_db.to_s
107
+ Log.info "==============="
108
+
109
+ # checking that content was modified according to the instance with minimal time
110
+ mod_db.each_instance { |checksum, size, content_mod_time, instance_mod_time, server, path|
111
+ next unless checksum.eql?(@mod_instance_checksum)
112
+ content_time = FileUtils.parse_time(content_mod_time.to_s)
113
+ assert_equal(MOD_TIME_INSTANCES, content_time)
114
+ instance_time = FileUtils.parse_time(instance_mod_time.to_s)
115
+ assert_equal(MOD_TIME_INSTANCES, instance_time)
116
+ }
117
+
118
+ # checking that files were actually modified
119
+ mod_db.each_instance { |checksum, size, content_mod_time, instance_mod_time, server, path|
120
+ indexer = FileIndexing::IndexAgent.new # (instance.server_name, instance.device)
121
+ patterns = FileIndexing::IndexerPatterns.new
122
+ patterns.add_pattern(File.dirname(path) + '/*') # this pattern index all files
123
+ indexer.index(patterns, mod_db)
124
+ p mod_db.to_s
125
+ p indexer.indexed_content.to_s
126
+ assert_equal(indexer.indexed_content, mod_db)
127
+ break
128
+ }
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,280 @@
1
+ # Author: Yaron Dror (yaron.dror.bb@gmail.com)
2
+ # Description: The file contains 'Param' module tests
3
+
4
+ require 'rspec'
5
+ require 'yaml'
6
+
7
+ require_relative '../../lib/params.rb'
8
+
9
+ module Params
10
+ # make private methods or Params public for testing capability.
11
+ public_class_method :parse_command_line_arguments, \
12
+ :raise_error_if_param_exists, :raise_error_if_param_does_not_exist, \
13
+ :read_yml_params, :override_param
14
+
15
+ module Spec
16
+
17
+ describe 'Params::parameter' do
18
+
19
+ it 'should define a new parameters' do
20
+ Params.string 'par_str', 'sss' ,'desc_str'
21
+ Params.integer 'par_int',1 , 'desc_int'
22
+ Params.float 'par_float',2.6 , 'desc_float'
23
+ Params.boolean 'par_true', true, 'desc_true'
24
+ Params.boolean 'par_false',false , 'desc_false'
25
+ Params['par_str'].should eq 'sss'
26
+ Params['par_int'].should eq 1
27
+ Params['par_float'].should eq 2.6
28
+ Params['par_true'].should eq true
29
+ Params['par_false'].should eq false
30
+ end
31
+
32
+ it 'should raise an error for wrong parameter type definition.' do
33
+ expect { Params::Param.new 'bad_type', 5, 'non_existing_type', 'desc_bad_type' }.to raise_error
34
+ end
35
+
36
+ it 'should raise an error when trying to define twice the same parameter' do
37
+ Params.string 'only_once', '1st' ,''
38
+ expect { Params.string 'only_once', '2nd' ,'' }.to raise_error \
39
+ "Parameter:'only_once', can only be defined once."
40
+ end
41
+ end
42
+
43
+ describe 'Params::read_yml_params' do
44
+ it 'should raise error when yml parameter is not defined' do
45
+ expect { Params::read_yml_params StringIO.new 'not_defined: 10' }.to raise_error \
46
+ "Parameter:'not_defined' has not been defined and can not be overridden. " \
47
+ "It should first be defined through Param module methods:" \
48
+ "Params.string, Params.path, Params.integer, Params.float, Params.complex, or Params.boolean."
49
+ end
50
+
51
+ it 'Will test yml parameter loading' do
52
+ # string to other. Will not raise error. Instead a cast is made.
53
+ Params.string('tmp4str', 'string_value', 'tmp4 def')
54
+ expect { Params::read_yml_params StringIO.new 'tmp4str: strr' }.to_not raise_error
55
+ expect { Params::read_yml_params StringIO.new 'tmp4str: 4' }.to_not raise_error
56
+ expect { Params::read_yml_params StringIO.new 'tmp4str: 4.5' }.to_not raise_error
57
+ expect { Params::read_yml_params StringIO.new 'tmp4str: true' }.to_not raise_error
58
+ expect { Params::read_yml_params StringIO.new 'tmp4str: false' }.to_not raise_error
59
+
60
+ # override integer with other types.
61
+ Params.integer('tmp4int', 1, 'tmp4 def')
62
+ expect { Params::read_yml_params StringIO.new 'tmp4int: strr' }.to raise_error \
63
+ "Parameter:'tmp4int' type:'Integer' but value type to override " \
64
+ "is:'String'."
65
+ expect { Params::read_yml_params StringIO.new 'tmp4int: 4' }.to_not raise_error
66
+ expect { Params::read_yml_params StringIO.new 'tmp4int: 4.5' }.to raise_error \
67
+ "Parameter:'tmp4int' type:'Integer' but value type to override " \
68
+ "is:'Float'."
69
+ expect { Params::read_yml_params StringIO.new 'tmp4int: true' }.to raise_error \
70
+ "Parameter:'tmp4int' type:'Integer' but value type to override " \
71
+ "is:'TrueClass'."
72
+ expect { Params::read_yml_params StringIO.new 'tmp4int: false' }.to raise_error \
73
+ "Parameter:'tmp4int' type:'Integer' but value type to override " \
74
+ "is:'FalseClass'."
75
+
76
+ # override float with other types.
77
+ Params.float('tmp4float', 1.1, 'tmp4 def')
78
+ expect { Params::read_yml_params StringIO.new 'tmp4float: strr' }.to raise_error \
79
+ "Parameter:'tmp4float' type:'Float' but value type to override " \
80
+ "is:'String'."
81
+ expect { Params::read_yml_params StringIO.new 'tmp4float: 4' }.to_not raise_error
82
+ expect { Params::read_yml_params StringIO.new 'tmp4float: 4.5' }.to_not raise_error
83
+ expect { Params::read_yml_params StringIO.new 'tmp4float: true' }.to raise_error \
84
+ "Parameter:'tmp4float' type:'Float' but value type to override " \
85
+ "is:'TrueClass'."
86
+ expect { Params::read_yml_params StringIO.new 'tmp4float: false' }.to raise_error \
87
+ "Parameter:'tmp4float' type:'Float' but value type to override " \
88
+ "is:'FalseClass'."
89
+ # override boolean with other types.
90
+ Params.boolean('tmp4true', true, 'tmp4 def')
91
+ expect { Params::read_yml_params StringIO.new 'tmp4true: strr' }.to raise_error \
92
+ "Parameter:'tmp4true' type:'Boolean' but value type to override " \
93
+ "is:'String'."
94
+ expect { Params::read_yml_params StringIO.new 'tmp4true: 4' }.to raise_error \
95
+ "Parameter:'tmp4true' type:'Boolean' but value type to override " \
96
+ "is:'Fixnum'."
97
+ expect { Params::read_yml_params StringIO.new 'tmp4true: 4.5' }.to raise_error \
98
+ "Parameter:'tmp4true' type:'Boolean' but value type to override " \
99
+ "is:'Float'."
100
+ expect { Params::read_yml_params StringIO.new 'tmp4true: true' }.to_not raise_error
101
+ expect { Params.read_yml_params StringIO.new 'tmp4true: false' }.to_not raise_error
102
+
103
+ Params.boolean('tmp4False', true, 'tmp4 def')
104
+ expect { Params.read_yml_params StringIO.new 'tmp4False: strr' }.to raise_error \
105
+ "Parameter:'tmp4False' type:'Boolean' but value type to override " \
106
+ "is:'String'."
107
+ expect { Params.read_yml_params StringIO.new 'tmp4False: 4' }.to raise_error \
108
+ "Parameter:'tmp4False' type:'Boolean' but value type to override " \
109
+ "is:'Fixnum'."
110
+ expect { Params.read_yml_params StringIO.new 'tmp4False: 4.5' }.to raise_error \
111
+ "Parameter:'tmp4False' type:'Boolean' but value type to override " \
112
+ "is:'Float'."
113
+ expect { Params.read_yml_params StringIO.new 'tmp4False: true' }.to_not raise_error
114
+ expect { Params.read_yml_params StringIO.new 'tmp4False: false' }.to_not raise_error
115
+
116
+ end
117
+
118
+ it 'should raise error when yml file format is bad' do
119
+ expect { Params.read_yml_params StringIO.new '"bad yml format' }.to raise_error
120
+ end
121
+
122
+ it 'should override defined values with yml values' do
123
+ Params.string('tmp5str', 'aaa', 'tmp5 def')
124
+ Params.integer('tmp5int', 11, 'tmp5 def')
125
+ Params.float('tmp5float', 11.11, 'tmp5 def')
126
+ Params.boolean('tmp5true', true, 'tmp5 def')
127
+ Params.boolean('tmp5false', false, 'tmp5 def')
128
+ Params.read_yml_params StringIO.new "tmp5str: bbb\ntmp5int: 12\ntmp5float: 12.12\n"
129
+ Params.read_yml_params StringIO.new "tmp5true: false\ntmp5false: true\n"
130
+ Params['tmp5str'].should eq 'bbb'
131
+ Params['tmp5int'].should eq 12
132
+ Params['tmp5float'].should eq 12.12
133
+ Params['tmp5true'].should eq false
134
+ Params['tmp5false'].should eq true
135
+ end
136
+ end
137
+
138
+ describe 'Params.parse_command_line_arguments' do
139
+ it 'should raise error when command line parameter is not defined' do
140
+ expect { Params.parse_command_line_arguments ['--new_param=9]'] }.to raise_error
141
+ end
142
+
143
+ it 'should parse parameter from command line.' do
144
+ # Override string with types.
145
+ Params.string('tmp6str', 'dummy', 'tmp6str def')
146
+ expect { Params.parse_command_line_arguments ['--tmp6str=9'] }.to_not raise_error
147
+ expect { Params.parse_command_line_arguments ['--tmp6str=8.1'] }.to_not raise_error
148
+ expect { Params.parse_command_line_arguments ['--tmp6str=ff'] }.to_not raise_error
149
+ expect { Params.parse_command_line_arguments ['--tmp6str=true'] }.to_not raise_error
150
+ expect { Params.parse_command_line_arguments ['--tmp6str=false'] }.to_not raise_error
151
+
152
+ # from fixnum to other types.
153
+ Params.integer('tmp6', 8, 'tmp6 def')
154
+ expect { Params.parse_command_line_arguments ['--tmp6=9'] }.to_not raise_error
155
+ expect { Params.parse_command_line_arguments ['--tmp6=8.1'] }.to raise_error
156
+ expect { Params.parse_command_line_arguments ['--tmp6=ff'] }.to raise_error
157
+ expect { Params.parse_command_line_arguments ['--tmp6=true'] }.to raise_error
158
+ expect { Params.parse_command_line_arguments ['--tmp6=false'] }.to raise_error
159
+
160
+ # from float to other types.
161
+ Params.float('tmp7', 8.9, 'tmp7 def')
162
+ # Casting fix num to float
163
+ expect { Params.parse_command_line_arguments ['--tmp7=9'] }.to_not raise_error
164
+ expect { Params.parse_command_line_arguments ['--tmp7=3.4'] }.to_not raise_error
165
+ expect { Params.parse_command_line_arguments ['--tmp7=ff'] }.to raise_error
166
+ expect { Params.parse_command_line_arguments ['--tmp7=true'] }.to raise_error
167
+ expect { Params.parse_command_line_arguments ['--tmp7=false'] }.to raise_error
168
+
169
+ # from TrueClass to other types.
170
+ Params.boolean('tmp8', true, 'tmp8 def')
171
+ expect { Params.parse_command_line_arguments ['--tmp8=9'] }.to_not raise_error
172
+ expect { Params.parse_command_line_arguments ['--tmp8=3.4'] }.to_not raise_error
173
+ expect { Params.parse_command_line_arguments ['--tmp8=ff'] }.to_not raise_error
174
+ expect { Params.parse_command_line_arguments ['--tmp8=true'] }.to_not raise_error
175
+ expect { Params.parse_command_line_arguments ['--tmp8=false'] }.to_not raise_error
176
+
177
+ # from FalseClass to other types.
178
+ Params.boolean('tmp9', false, 'tmp9 def')
179
+ expect { Params.parse_command_line_arguments ['--tmp9=9'] }.to_not raise_error
180
+ expect { Params.parse_command_line_arguments ['--tmp9=3.4'] }.to_not raise_error
181
+ expect { Params.parse_command_line_arguments ['--tmp9=ff'] }.to_not raise_error
182
+ expect { Params.parse_command_line_arguments ['--tmp9=true'] }.to_not raise_error
183
+ expect { Params.parse_command_line_arguments ['--tmp9=false'] }.to_not raise_error
184
+ end
185
+ end
186
+
187
+ describe 'Params.init' do
188
+ it 'should override command line arguments correctly.' do
189
+ File.stub(:exist?).and_return false
190
+ # Override string with types.
191
+ Params.string('tmp6str2', 'dummy', 'tmp6str def')
192
+ expect { Params.init ['--tmp6str2=9'] }.to_not raise_error
193
+ expect { Params.init ['--tmp6str2=8.1'] }.to_not raise_error
194
+ expect { Params.init ['--tmp6str2=ff'] }.to_not raise_error
195
+ expect { Params.init ['--tmp6str2=true'] }.to_not raise_error
196
+ expect { Params.init ['--tmp6str2=false'] }.to_not raise_error
197
+
198
+ # from fixnum to other types.
199
+ Params.integer('tmp6Fixnum2', 8, 'tmp6 def')
200
+ expect { Params.init ['--tmp6Fixnum2=9'] }.to_not raise_error
201
+ expect { Params.init ['--tmp6Fixnum2=8.1'] }.to raise_error
202
+ expect { Params.init ['--tmp6Fixnum2=ff'] }.to raise_error
203
+ expect { Params.init ['--tmp6Fixnum2=true'] }.to raise_error
204
+ expect { Params.init ['--tmp6Fixnum2=false'] }.to raise_error
205
+
206
+ # from float to other types.
207
+ Params.float('tmp7float2', 8.9, 'tmp7 def')
208
+ # Casting fix num to float
209
+ expect { Params.init ['--tmp7float2=9'] }.to_not raise_error
210
+ expect { Params.init ['--tmp7float2=3.4'] }.to_not raise_error
211
+ expect { Params.init ['--tmp7float2=ff'] }.to raise_error
212
+ expect { Params.init ['--tmp7float2=true'] }.to raise_error
213
+ expect { Params.init ['--tmp7float2=false'] }.to raise_error
214
+
215
+ # from TrueClass to other types.
216
+ Params.boolean('tmp8true2', true, 'tmp8 def')
217
+ expect { Params.init ['--tmp8true2=9'] }.to raise_error
218
+ expect { Params.init ['--tmp8true2=3.4'] }.to raise_error
219
+ expect { Params.init ['--tmp8true2=ff'] }.to raise_error
220
+ expect { Params.init ['--tmp8true2=true'] }.to_not raise_error
221
+ expect { Params.init ['--tmp8true2=false'] }.to_not raise_error
222
+
223
+ # from FalseClass to other types.
224
+ Params.boolean('tmp9false2', false, 'tmp9 def')
225
+ expect { Params.init ['--tmp9false2=9'] }.to raise_error
226
+ expect { Params.init ['--tmp9false2=3.4'] }.to raise_error
227
+ expect { Params.init ['--tmp9false2=ff'] }.to raise_error
228
+ expect { Params.init ['--tmp9false2=true'] }.to_not raise_error
229
+ expect { Params.init ['--tmp9false2=false'] }.to_not raise_error
230
+ end
231
+
232
+ it 'should override defined values with command line values' do
233
+ File.stub(:exist?).and_return false
234
+ Params.string('tmp10str', 'aaa', 'tmp10 def')
235
+ Params.integer('tmp10int', 11, 'tmp10 def')
236
+ Params.float('tmp10float', 11.11, 'tmp10 def')
237
+ Params.boolean('tmp10true', true, 'tmp10 def')
238
+ Params.boolean('tmp10false', false, 'tmp10 def')
239
+ Params.init ['--tmp10str=bbb', '--tmp10int=12', '--tmp10float=12.12', \
240
+ '--tmp10true=false', '--tmp10false=true']
241
+ Params['tmp10str'].should eq 'bbb'
242
+ Params['tmp10int'].should eq 12
243
+ Params['tmp10float'].should eq 12.12
244
+ Params['tmp10true'].should eq false
245
+ Params['tmp10false'].should eq true
246
+ end
247
+
248
+ it 'init should override parameters with file and command' do
249
+ Params.string('init_param', 'code', '')
250
+ File.stub(:exist?).and_return true
251
+ File.stub(:open).and_return StringIO.new 'init_param: yml'
252
+ Params.init ['--conf_file=dummy_file', '--init_param=command-line']
253
+ Params['init_param'].should eq 'command-line'
254
+ end
255
+
256
+ it 'init should override parameters with file only' do
257
+ Params.string('init_param2', 'code', '')
258
+ File.stub(:exist?).and_return true
259
+ File.stub(:open).and_return StringIO.new 'init_param2: yml'
260
+ Params.init ['--conf_file=dummy_file']
261
+ Params['init_param2'].should eq 'yml'
262
+ end
263
+
264
+ it 'init should override parameters with command line only' do
265
+ Params.string('init_param3', 'code', '')
266
+ File.stub(:exist?).and_return false
267
+ Params.init ['--init_param3=command-line']
268
+ Params['init_param3'].should eq 'command-line'
269
+ end
270
+
271
+ it 'init should not override any parameters' do
272
+ Params.string('init_param4', 'code', '')
273
+ File.stub(:exist?).and_return false
274
+ Params.init []
275
+ Params['init_param4'].should eq 'code'
276
+ end
277
+ end
278
+ end
279
+ end
280
+
@@ -0,0 +1,43 @@
1
+ # Author: Yaron Dror (yaron.dror.bb@gmail.com)
2
+ # Description: Params test file.
3
+ # run: rake test.
4
+ # Note: This file will be tested along with all project tests.
5
+
6
+ require 'params'
7
+ require 'test/unit'
8
+ require_relative '../../lib/params.rb'
9
+
10
+
11
+ class TestLog < Test::Unit::TestCase
12
+
13
+ def test_parsing_of_the_defined_parameters
14
+ # Define options
15
+ Params.integer('remote_server1', 3333,
16
+ 'Listening port for backup server content data.')
17
+ Params.string('backup_username1', 'tmp', 'Backup server username.')
18
+ Params.string('backup_password1', 'tmp', 'Backup server password.')
19
+ Params.string('backup_destination_folder1', '',
20
+ 'Backup server destination folder, default is the relative local folder.')
21
+ Params.string('content_data_path1', File.expand_path('~/.bbfs/var/content.data'),
22
+ 'ContentData file path.')
23
+ Params.string('monitoring_config_path1', File.expand_path('~/.bbfs/etc/file_monitoring.yml'),
24
+ 'Configuration file for monitoring.')
25
+ Params.float('time_to_start1', 0.03,
26
+ 'Time to start monitoring')
27
+
28
+ cmd = ['--remote_server1=2222', '--backup_username1=rami', '--backup_password1=kavana',
29
+ '--backup_destination_folder1=C:\Users\Alexey\Backup',
30
+ '--content_data_path1=C:\Users\Alexey\Content',
31
+ '--monitoring_config_path1=C:\Users\Alexey\Config',
32
+ '--time_to_start1=1.5']
33
+ Params.init cmd
34
+ assert_equal(2222, Params['remote_server1'])
35
+ assert_equal('rami', Params['backup_username1'])
36
+ assert_equal('kavana', Params['backup_password1'])
37
+ assert_equal('C:\Users\Alexey\Backup', Params['backup_destination_folder1'])
38
+ assert_equal('C:\Users\Alexey\Content', Params['content_data_path1'])
39
+ assert_equal('C:\Users\Alexey\Config', Params['monitoring_config_path1'])
40
+ assert_equal(1.5, Params['time_to_start1'])
41
+ end
42
+ end
43
+
@@ -0,0 +1,122 @@
1
+ require 'test/unit'
2
+ require 'run_in_background'
3
+
4
+ # TODO break to number of small tests according to functionality
5
+ # TODO rewrite with Shoulda/RSpec
6
+ class TestRunInBackground < Test::Unit::TestCase
7
+ #include RunInBackground
8
+
9
+ if RUBY_PLATFORM =~ /linux/ or RUBY_PLATFORM =~ /darwin/
10
+ OS = :LINUX
11
+ elsif RUBY_PLATFORM =~ /mingw/ or RUBY_PLATFORM =~ /ms/ or RUBY_PLATFORM =~ /win/
12
+ require 'sys/uname'
13
+ OS = :WINDOWS
14
+ else
15
+ raise "Unsupported platform #{RUBY_PLATFORM}"
16
+ end
17
+
18
+ def setup
19
+ @good_daemon = "good_daemon_test"
20
+ @good_daemonize = "good_daemonize_test"
21
+ @good_win32daemon = "good_win32daemon_test"
22
+ @bad_daemon = "bad_daemon_test"
23
+ @binary = File.join(File.dirname(File.expand_path(__FILE__)), 'test_app')
24
+ @binary.tr!('/','\\') if OS == :WINDOWS
25
+ File.chmod(0755, @binary) if OS == :LINUX && !File.executable?(@binary)
26
+ @absent_binary = File.join(File.dirname(File.expand_path(__FILE__)), "test_app_absent")
27
+ end
28
+
29
+ def test_functionality
30
+ if OS == :WINDOWS && Sys::Uname.sysname =~ /(Windows 7)/
31
+ skip "This test shouldn't be run on #{$1}"
32
+ end
33
+
34
+ # test start
35
+ # test application should actually start here
36
+ assert_nothing_raised{ RunInBackground.start(@binary, ["1000"], @good_daemon) }
37
+ assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, ["1000"], @bad_daemon) }
38
+
39
+ # start arguments have to be defined
40
+ assert_raise(ArgumentError) { RunInBackground.start(["1000"], @bad_daemon) }
41
+ assert_raise(ArgumentError) { RunInBackground.start(nil, ["1000"], @bad_daemon) }
42
+ assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, nil, @bad_daemon) }
43
+ assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, ["1000"], nil) }
44
+
45
+ # test exists?
46
+ assert_raise(ArgumentError) { RunInBackground.exists? }
47
+ assert_equal(false, RunInBackground.exists?(@bad_daemon))
48
+ assert_equal(true, RunInBackground.exists?(@good_daemon))
49
+
50
+ # test running?
51
+ # if stop method will be public need to add test checks actually stopped daemon
52
+ assert_raise(ArgumentError) { RunInBackground.running? }
53
+ assert_raise(ArgumentError) { RunInBackground.running?(@bad_daemon) }
54
+ assert_equal(true, RunInBackground.running?(@good_daemon))
55
+
56
+ # test daemonazing (start!)
57
+ # from the nature of daemonization need to run it from another process that will be daemonized
58
+ ruby = (OS == :WINDOWS ? RunInBackground::RUBY_INTERPRETER_PATH : "ruby")
59
+ cmd = "#{ruby} -Ilib #{@binary} 50 #{@good_daemonize}"
60
+ pid = spawn(cmd)
61
+ Process.waitpid pid
62
+ # checking that it indeed was daemonized
63
+ # e.i. process was killed and code rerun in background
64
+ # it takes time to the OS to remove process, so using a timeout here
65
+ 0.upto(RunInBackground::TIMEOUT) do
66
+ begin
67
+ Process.kill(0, pid)
68
+ rescue Errno::ESRCH
69
+ break
70
+ end
71
+ sleep 1
72
+ end
73
+ assert_raise(Errno::ESRCH) { Process.kill(0, pid) }
74
+ assert_equal(true, RunInBackground.exists?(@good_daemonize))
75
+ assert_equal(true, RunInBackground.running?(@good_daemonize))
76
+
77
+ # test running win32 specific daemon (start_win32service)
78
+ # wrapper script will be run
79
+ if OS == :WINDOWS
80
+ win32service_arg = [RunInBackground::RUBY_INTERPRETER_PATH, @binary, 1000]
81
+ assert_nothing_raised{
82
+ RunInBackground.start_win32service(RunInBackground::WRAPPER_SCRIPT,
83
+ win32service_arg, @good_win32daemon)
84
+ }
85
+ assert_equal(true, RunInBackground.exists?(@good_win32daemon))
86
+ assert_equal(true, RunInBackground.running?(@good_win32daemon))
87
+ else
88
+ assert_raise(NotImplementedError) {
89
+ RunInBackground.start_win32service(@absent_binary, [], @bad_daemon)
90
+ }
91
+ end
92
+
93
+ # uncomment following lines if there is a suspicion that something gone wrong
94
+ # inspired by bug caused by coworking of daemon_wrapper an logger
95
+ #sleep 10
96
+ #assert_equal(true, RunInBackground.running?(@good_daemon))
97
+ #assert_equal(true, RunInBackground.running?(@good_daemonize))
98
+ #assert_equal(true, RunInBackground.running?(@good_win32daemon))
99
+
100
+ # test delete
101
+ # test application should actually stop here
102
+ assert_raise(ArgumentError) { RunInBackground.delete }
103
+ assert_raise(ArgumentError) { RunInBackground.delete(@bad_daemon) }
104
+ assert_nothing_raised { RunInBackground.delete(@good_daemon) }
105
+ assert_equal(false, RunInBackground.exists?(@good_daemon))
106
+
107
+ assert_nothing_raised { RunInBackground.delete(@good_daemonize) }
108
+ assert_equal(false, RunInBackground.exists?(@good_daemonize))
109
+
110
+ # actuall only for Windows platform
111
+ if RunInBackground.exists?(@good_win32daemon)
112
+ assert_nothing_raised { RunInBackground.delete(@good_win32daemon) }
113
+ assert_equal(false, RunInBackground.exists?(@good_win32daemon))
114
+ end
115
+ end
116
+
117
+ def teardown
118
+ RunInBackground.delete @good_daemon if RunInBackground.exists? @good_daemon
119
+ RunInBackground.delete @good_daemonize if RunInBackground.exists? @good_daemonize
120
+ RunInBackground.delete @good_win32daemon if RunInBackground.exists? @good_win32daemon
121
+ end
122
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Toy script used for RunInBackground tests.
4
+ # usage: $0 number_of_iterations [daemon_name_if_daemonized]
5
+
6
+ DBG = false # NOTE be sure to disable it in production
7
+
8
+ begin
9
+ begin
10
+ require 'log'
11
+ require 'params'
12
+ rescue LoadError
13
+ $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '..', '..', 'lib'))
14
+ $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '..', '..'))
15
+ require 'log'
16
+ require 'params'
17
+ end
18
+
19
+ # On WindowsXP log can be found under:
20
+ # C:/Documents and Settings/NetworkService/.bbfs/test_app_<pid>.log
21
+ Params['log_file_name'] = File.join(Dir.home, '.bbfs', "#{File.basename(__FILE__)}_#{Process.pid}.log")
22
+ Params['log_write_to_console'] = false
23
+ if DBG
24
+ Params['log_debug_level'] = 1
25
+ Log.init
26
+ end
27
+
28
+ # app should be run in background
29
+ if ARGV.size == 2
30
+ begin
31
+ require 'run_in_background'
32
+ rescue LoadError
33
+ $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '..', '..', 'lib'))
34
+ $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), '..', '..'))
35
+ require 'run_in_background'
36
+ end
37
+
38
+ Log.debug1 "Before run in background: PID #{Process.pid}"
39
+ # ARGV.pop returns frozen string and thus causes a failure of Service.create
40
+ # to fix it new string with the same content created.
41
+ RunInBackground.start!(String.new(ARGV.pop))
42
+ # if got here then error
43
+ Log.error "After run in background: ERROR"
44
+ end
45
+
46
+ max = (ARGV.size > 0 && ARGV[0] != nil && ARGV[0].to_i > 0)? ARGV[0].to_i : 200
47
+
48
+ while max > 0
49
+ Log.debug1 "#{max}"
50
+ sleep 1
51
+ max -= 1
52
+ end
53
+
54
+ rescue Exception => err
55
+ Log.error "Wrapper error: #{err}"
56
+ raise
57
+ end