summaryrefslogtreecommitdiff
path: root/test/tc_byteback_snapshot.rb
blob: 87b6409b0dbce3e6b5bfe11ad96634cbc18107ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
$: << File.dirname(__FILE__)+"/../lib"

require 'test/unit'
require 'byteback/backup_directory'
require 'time'
# require 'mocha/test_unit'

class SnapshotTest < Test::Unit::TestCase

  def setup

  end

  def teardown

  end

  #
  # This class is supposed to work out which bits get pruned first
  #
  def test_sort_by_importance

    start = Time.now
      
    15.times do |limit|
      limit += 1
      biggest_offset = nil 
      backups = []
      offsets = []
      now   = Time.at(start.to_i) + rand(7)*86400
      day   = 0

      #
      # Do this test until we reach a maximum age
      #
      while true do

        backups << Byteback::Snapshot.new("/tmp", File.join("/tmp/",now.iso8601))

        while backups.length > limit do
          sorted_backups = Byteback::Snapshot.sort_by_importance(backups, now)
          backups.delete(sorted_backups.last)
        end

        offsets = backups.collect{|x| ((now - x.time)/86400.0).round }
 
        #
        # Each backup should have backups for the last 7 days, then the first four Sundays, and then the next mod 28 day after that
        #
        mod_28 = ((now.to_i / 86400.0).floor % 28 - 3)

        targets = ((0..6).to_a + 
          [7,14,21,28].to_a.collect{|i| i + now.wday} +
          [2*28 + mod_28]).select{|t| t < day}.first(limit).reverse

        assert_equal(targets - offsets, [], "Failed after day #{day} (#{now.wday}) for a limit of #{limit} backups")

        if biggest_offset.nil? or offsets.max > biggest_offset
          biggest_offset = offsets.max
        else
          puts "Oldest backup with space for #{limit} backups is #{offsets.max} days: #{offsets.join(", ")}"
          break
        end

        # Move on a day
        day += 1
        now += 86400
      end
    end
  end

  #
  # This run the same test as above, execpt with 3 hosts all competeing for space
  #
  def test_sort_by_importance_with_multiple_hosts
    start = Time.now
      
    40.times do |limit|
      limit += 6
      biggest_offset = nil 
      backups = []
      offsets = []
      now   = Time.at(start.to_i) + rand(7)*86400
      day   = 0

      #
      # Do this test until we reach a maximum age
      #
      while true do

        %w(host1 host2 host3).each do |host|
           backups << Byteback::Snapshot.new("/tmp/#{host}", File.join("/tmp/#{host}/",(now+rand(3600)).iso8601 ))
        end

        while backups.length > limit do
          sorted_backups = Byteback::Snapshot.sort_by_importance(backups, now)
          backups.delete(sorted_backups.last)
        end

        offsets = backups.collect{|x| ((now - x.time)/86400.0).round }

        #
        # TODO test me!
        #
 
        if biggest_offset.nil? or offsets.max > biggest_offset
          biggest_offset = offsets.max
        else
          puts "Oldest backup with space for #{limit} backups and 3 hosts is #{offsets.max} days: #{offsets.join(", ")}"
          break
        end

        # Move on a day
        day += 1
        now += 86400
      end
    end
  end

  #
  # This test is the same as the previous two, except with random failures added in.
  #
  def test_sort_by_importance_with_random_failures

    start = Time.now
      
    15.times do 
      limit = 15
      backups = []
      offsets = []
      now   = Time.at(start.to_i) + rand(7)*86400
      day   = 0

      #
      # Run this test over 120 days
      #
      120.times do

        # Fail on 3 days out of four
        if rand(7) < 3 
          backups << Byteback::Snapshot.new("/tmp", File.join("/tmp/",now.iso8601))
        end

        while backups.length > limit do
          sorted_backups = Byteback::Snapshot.sort_by_importance(backups, now)
          backups.delete(sorted_backups.last)
        end

        offsets = backups.collect{|x| ((now - x.time)/86400.0).round }

        # TODO test! 

        # Move on a day
        day += 1
        now += 86400
      end
      puts "Oldest backup with space for #{limit} backups is #{offsets.max} days: #{offsets.join(", ")}"

    end
  end
end