github.com/wtsi-ssg/wrstat/v4@v4.5.1/basedirs/history_test.go (about) 1 /******************************************************************************* 2 * Copyright (c) 2023 Genome Research Ltd. 3 * 4 * Authors: 5 * Sendu Bala <sb10@sanger.ac.uk> 6 * Michael Woolnough <mw31@sanger.ac.uk> 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining 9 * a copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 ******************************************************************************/ 27 28 package basedirs 29 30 import ( 31 "testing" 32 "time" 33 34 . "github.com/smartystreets/goconvey/convey" 35 ) 36 37 func TestHistory(t *testing.T) { 38 now := time.Now() 39 40 quotaMax := 1000000 41 quotaUsageStart := 1 42 dy := float64(quotaMax - quotaUsageStart) 43 changeDays := float64(2) 44 usageFor4Years := changeDays * dy / (4 * 365) 45 usageFor6Years := changeDays * dy / (6 * 365) 46 47 for _, test := range [...]struct { 48 Name string 49 Histories []History 50 UntilSize time.Time 51 UntilInodes time.Time 52 }{ 53 { 54 Name: "Zero history produces no dates", 55 Histories: nil, 56 UntilSize: time.Time{}, 57 UntilInodes: time.Time{}, 58 }, 59 { 60 Name: "A Single item in History produces no dates", 61 Histories: []History{ 62 { 63 Date: now, 64 UsageSize: 2, 65 QuotaSize: 10, 66 UsageInodes: 1, 67 QuotaInodes: 20, 68 }, 69 }, 70 UntilSize: time.Time{}, 71 UntilInodes: time.Time{}, 72 }, 73 { 74 Name: "A Single item in History, with Quotas full produces now", 75 Histories: []History{ 76 { 77 Date: now, 78 UsageSize: 10, 79 QuotaSize: 10, 80 UsageInodes: 20, 81 QuotaInodes: 20, 82 }, 83 }, 84 UntilSize: now, 85 UntilInodes: now, 86 }, 87 { 88 Name: "A Single item in History, with Quotas over-full produces now", 89 Histories: []History{ 90 { 91 Date: now, 92 UsageSize: 20, 93 QuotaSize: 10, 94 UsageInodes: 30, 95 QuotaInodes: 20, 96 }, 97 }, 98 UntilSize: now, 99 UntilInodes: now, 100 }, 101 { 102 Name: "Two items in History produces useful predicted dates", 103 Histories: []History{ 104 { 105 Date: now.Add(-24 * time.Hour), 106 UsageSize: 5, 107 QuotaSize: 100, 108 UsageInodes: 0, 109 QuotaInodes: 20, 110 }, 111 { 112 Date: now, 113 UsageSize: 20, 114 QuotaSize: 100, 115 UsageInodes: 10, 116 QuotaInodes: 20, 117 }, 118 }, 119 UntilSize: now.Add(secondsInDay*5 + 8*time.Hour), 120 UntilInodes: now.Add(secondsInDay * 1), 121 }, 122 { 123 Name: "Two items in history, with no change in size, and inodes at quota" + 124 " produces no date for size and now for inodes", 125 Histories: []History{ 126 { 127 Date: time.Now().Add(-25 * time.Hour), 128 UsageSize: 5, 129 QuotaSize: 100, 130 UsageInodes: 0, 131 QuotaInodes: 20, 132 }, 133 { 134 Date: time.Now(), 135 UsageSize: 5, 136 QuotaSize: 100, 137 UsageInodes: 20, 138 QuotaInodes: 20, 139 }, 140 }, 141 UntilSize: time.Time{}, 142 UntilInodes: now, 143 }, 144 { 145 Name: "Two items in history, with a downward trend for size and inodes, produces no dates", 146 Histories: []History{ 147 { 148 Date: time.Now().Add(-24 * time.Hour), 149 UsageSize: 50, 150 QuotaSize: 100, 151 UsageInodes: 50, 152 QuotaInodes: 20, 153 }, 154 { 155 Date: time.Now(), 156 UsageSize: 10, 157 QuotaSize: 100, 158 UsageInodes: 0, 159 QuotaInodes: 20, 160 }, 161 }, 162 UntilSize: time.Time{}, 163 UntilInodes: time.Time{}, 164 }, 165 { 166 Name: "Three items in history correctly uses the last and third from last items to predict dates.", 167 Histories: []History{ 168 { 169 Date: time.Now().Add(-48 * time.Hour), 170 UsageSize: 0, 171 QuotaSize: 100, 172 UsageInodes: 0, 173 QuotaInodes: 20, 174 }, 175 { 176 Date: time.Now().Add(-24 * time.Hour), 177 UsageSize: 5, 178 QuotaSize: 100, 179 UsageInodes: 5, 180 QuotaInodes: 20, 181 }, 182 { 183 Date: time.Now(), 184 UsageSize: 5, 185 QuotaSize: 100, 186 UsageInodes: 10, 187 QuotaInodes: 20, 188 }, 189 }, 190 UntilSize: now.Add(secondsInDay * 38), 191 UntilInodes: now.Add(secondsInDay * 2), 192 }, 193 { 194 Name: "Four items in history correctly uses the last and third from last items to predict dates.", 195 Histories: []History{ 196 { 197 Date: time.Now().Add(-72 * time.Hour), 198 UsageSize: 100, 199 QuotaSize: 100, 200 UsageInodes: 100, 201 QuotaInodes: 20, 202 }, 203 { 204 Date: time.Now().Add(-48 * time.Hour), 205 UsageSize: 0, 206 QuotaSize: 100, 207 UsageInodes: 0, 208 QuotaInodes: 20, 209 }, 210 { 211 Date: time.Now().Add(-24 * time.Hour), 212 UsageSize: 5, 213 QuotaSize: 100, 214 UsageInodes: 5, 215 QuotaInodes: 20, 216 }, 217 { 218 Date: time.Now(), 219 UsageSize: 5, 220 QuotaSize: 100, 221 UsageInodes: 10, 222 QuotaInodes: 20, 223 }, 224 }, 225 UntilSize: now.Add(secondsInDay * 38), 226 UntilInodes: now.Add(secondsInDay * 2), 227 }, 228 { 229 Name: "Predictions beyond 5 years are treated as not running out.", 230 Histories: []History{ 231 { 232 Date: time.Now().Add(-(time.Duration(changeDays * 24)) * time.Hour), 233 UsageSize: uint64(quotaUsageStart), 234 QuotaSize: uint64(quotaMax), 235 UsageInodes: uint64(quotaUsageStart), 236 QuotaInodes: uint64(quotaMax), 237 }, 238 { 239 Date: time.Now().Add(-24 * time.Hour), 240 UsageSize: uint64(quotaUsageStart), 241 QuotaSize: uint64(quotaMax), 242 UsageInodes: uint64(quotaUsageStart), 243 QuotaInodes: uint64(quotaMax), 244 }, 245 { 246 Date: time.Now(), 247 UsageSize: uint64(usageFor6Years), 248 QuotaSize: uint64(quotaMax), 249 UsageInodes: uint64(usageFor4Years), 250 QuotaInodes: uint64(quotaMax), 251 }, 252 }, 253 UntilSize: time.Time{}, 254 UntilInodes: now.Add(secondsInDay * 4 * 365), 255 }, 256 } { 257 Convey(test.Name, t, func() { 258 untilSize, untilInodes := DateQuotaFull(test.Histories) 259 260 marginOfError := int64(2) 261 262 if time.Until(untilInodes) > 3*365*24*time.Hour { 263 marginOfError = 15000 264 } 265 266 So(untilSize.Unix(), ShouldBeBetween, test.UntilSize.Unix()-marginOfError, test.UntilSize.Unix()+marginOfError) 267 So(untilInodes.Unix(), ShouldBeBetween, test.UntilInodes.Unix()-marginOfError, test.UntilInodes.Unix()+marginOfError) 268 }) 269 } 270 }