1####################################################### 2# 3# Redmine#6584: file_select mtime consistency 4# 5####################################################### 6body common control 7{ 8 inputs => { "../../default.cf.sub" }; 9 bundlesequence => { default("$(this.promise_filename)") }; 10 version => "1.0"; 11} 12 13bundle common g 14{ 15 vars: 16 "datafile" string => "$(this.promise_dirname)/rules.json"; 17} 18bundle agent init 19{ 20 vars: 21 "files" 22 slist => { "file1.log", "file2.log", "file3.log" }, 23 comment => "These are the files we will try to delete"; 24 25 "tests" 26 slist => { 27 "test_delete_with_spec_from_data", 28 "test_delete_with_spec_from_policy", 29 }, 30 comment => "We have two tests combined here because they should be kept in sync."; 31 32 "data" data => readjson($(g.datafile), 1M); 33 "idx" slist => getindices("data"); 34 35 files: 36 "$(G.testdir)/$(tests)/$(data[$(idx)][location])/." 37 create => "true", 38 comment => "Make sure our directories exist so that files can be created"; 39 40 "$(G.testdir)/$(tests)/$(data[$(idx)][location])/$(files)" 41 create => "true", 42 comment => "Make sure the files exist so they can be deleted"; 43 44 commands: 45 "$(G.touch)" 46 args => "-a -m -t 200901181205.09 $(G.testdir)/$(tests)/$(data[$(idx)][location])/$(files)", 47 comment => "Make sure the files are 'old' so they will be selected for deletion"; 48} 49 50bundle agent test 51{ 52 meta: 53 "test_soft_fail" 54 string => "any", 55 meta => { "redmine#6584", "zendesk#1466" }; 56 57 methods: 58 "Test delete with spec from policy" 59 usebundle => test_delete_with_spec_from_policy; 60 61 "Test delete with spec from data" 62 usebundle => test_delete_with_spec_from_data($(g.datafile)); 63} 64 65bundle agent test_delete_with_spec_from_policy { 66 files: 67 # This promise should be an effictive mirror of the promise with handle 'test_delete_with_spec_from_data' 68 "$(G.testdir)/$(this.bundle)/tmp/logs/tidy" 69 delete => tidy, 70 file_select => 71 select_file_with_extension_retention_mtime(".*.log", # == 'filter' key in JSON 72 "plain", # == 'type' key in JSON 73 "2", # == 'retention' key in JSON 74 "$(G.testdir)/$(this.bundle)/tmp/logs/tidy"), # == 'location' key in JSON 75 depth_search => recurse("2"), # == 'depth' key in JSON 76 action => if_elapsed_inform("10"), # == 'frequency' key in JSON 77 if => "any"; # == 'context' key in JSON 78 79 reports: 80 DEBUG:: 81 "'$(G.testdir)/$(this.bundle)/tmp/logs/tidy'"; 82} 83 84bundle agent test_delete_with_spec_from_data(ref) 85{ 86 vars: 87 "input_cleanup" 88 comment => "Read json file into container", 89 data => readjson("${ref}", 1024); 90 91 "i" 92 comment => "Get index of json for iteration", 93 slist => getindices("input_cleanup"); 94 95 methods: 96 "do_cleanup" usebundle => do_cleanup("${input_cleanup[${i}][location]}", 97 "${input_cleanup[${i}][context]}", 98 "${input_cleanup[${i}][action]}", 99 "${input_cleanup[${i}][frequency]}", 100 "${input_cleanup[${i}][type]}", 101 "${input_cleanup[${i}][filter]}", 102 "${input_cleanup[${i}][retention]}", 103 "${input_cleanup[${i}][depth]}", 104 "${input_cleanup[${i}][size]}", 105 "${input_cleanup[${i}][reason]}"); 106 107 reports: 108 DEBUG:: 109 " # Spec from json data file '$(ref)'# 110location => ${input_cleanup[${i}][location]} 111context => ${input_cleanup[${i}][context]} 112action => ${input_cleanup[${i}][action]} 113frequency => ${input_cleanup[${i}][frequency]} 114type => ${input_cleanup[${i}][type]} 115filter => ${input_cleanup[${i}][filter]} 116retention => ${input_cleanup[${i}][retention]} 117depth => ${input_cleanup[${i}][depth]} 118size => ${input_cleanup[${i}][size]} 119reason => ${input_cleanup[${i}][reason]} 120"; 121} 122 123 124 125bundle agent do_cleanup(location, 126 context, 127 action, 128 frequency, 129 type, 130 filter, 131 retention, 132 depth, 133 size, 134 reason) { 135 classes: 136 #"action_tidy" expression => strcmp("$(action)", "TIDY"); 137 #"action_rotate" expression => strcmp("$(action)", "ROTATE"); 138 #"requested_size" expression => regcmp("[0-9]*", "$(size)"); 139 140 files: 141 #action_tidy:: 142 "$(G.testdir)/test_delete_with_spec_from_data/$(location)" 143 handle => "test_delete_with_spec_from_data", 144 delete => tidy, 145 file_select => select_file_with_extension_retention_mtime("$(filter)", 146 "$(type)", 147 "$(retention)", 148 "$(G.testdir)/test_delete_with_spec_from_data/$(location)"), 149 depth_search => recurse("$(depth)"), 150 action => if_elapsed_inform("$(frequency)"), 151 if => "$(context)"; 152 153 reports: 154 DEBUG:: 155 "Filter=$(filter) Type=$(type) Retension=$(retention) Location=$(G.testdir)/test_delete_with_spec_from_data/$(location).* Depth=$(depth) Freq=$(frequency) Context=$(context)"; 156} 157 158bundle agent check 159{ 160 vars: 161 "files[test_delete_with_spec_from_data]" slist => lsdir("$(G.testdir)/test_delete_with_spec_from_data/tmp/logs/tidy", ".*.log", "false"); 162 "files[test_delete_with_spec_from_policy]" slist => lsdir("$(G.testdir)/test_delete_with_spec_from_policy/tmp/logs/tidy", ".*.log", "false"); 163 164 "count_files[test_delete_with_spec_from_data]" 165 int => length("files[test_delete_with_spec_from_data]") 166 ; 167 "count_files[test_delete_with_spec_from_policy]" 168 int => length("files[test_delete_with_spec_from_policy]"); 169 170 "files_in_tidy_dir_count_$(init.tests)" int => length("files_in_tidy_dir[$(init.tests)]"); 171 "OK_tests" slist => maplist("OK_$(this)", @(init.tests)); 172 173 classes: 174 "OK_$(init.tests)" 175 not => isgreaterthan("$(count_files[$(init.tests)])", 0), 176 comment => "Define a class for each test that has an empty directory as desired"; 177 178 "OK" 179 and => { @(OK_tests) }, 180 comment => "Pass if all tests are OK"; 181 182 reports: 183 DEBUG:: 184 "files[test_delete_with_spec_from_data] = $(files[test_delete_with_spec_from_data])"; 185 "files[test_delete_with_spec_from_policy] = $(files[test_delete_with_spec_from_policy])"; 186 "count_files[test_delete_with_spec_from_data] = $(count_files[test_delete_with_spec_from_data])"; 187 "count_files[test_delete_with_spec_from_policy] = $(count_files[test_delete_with_spec_from_policy])"; 188 189 "$(init.tests) pass" 190 if => "OK_$(init.tests)"; 191 192 "$(init.tests) fail" 193 if => "!OK_$(init.tests)"; 194 195 OK:: 196 "$(this.promise_filename) Pass"; 197 198 !OK:: 199 "$(this.promise_filename) FAIL"; 200} 201body file_select select_file_with_extension_retention_mtime(filter, type, days_old, location) { 202 mtime => irange(0, ago(0, 0, $(days_old), 0, 0, 0)); 203 path_name => { "$(location)/.*" }; 204 leaf_name => { "$(filter)" }; 205 file_types => { "$(type)" }; 206# The intention is to select files older than x days (mtime between now and x days ago should be retained) I believe the second file_result is correct. 207# file_result => "mtime.path_name.leaf_name.file_types"; # Oddly this works for test_delete_with_spec_from_policy, but not with test_delete_with_spec_from_data 208 file_result => "!mtime.path_name.leaf_name.file_types"; # Oddly this works for test_delete_with_spec_from_data, but not with test_delete_with_spec_from_policy 209} 210 211body action if_elapsed_inform(x) { 212 report_level => "inform"; 213 ifelapsed => "$(x)"; 214 expireafter => "$(x)"; 215} 216