stat.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2015 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package fusetesting
  15. import (
  16. "fmt"
  17. "os"
  18. "reflect"
  19. "syscall"
  20. "time"
  21. "github.com/jacobsa/oglematchers"
  22. )
  23. // Match os.FileInfo values that specify an mtime equal to the given time.
  24. func MtimeIs(expected time.Time) oglematchers.Matcher {
  25. return oglematchers.NewMatcher(
  26. func(c interface{}) error { return mtimeIsWithin(c, expected, 0) },
  27. fmt.Sprintf("mtime is %v", expected))
  28. }
  29. // Like MtimeIs, but allows for a tolerance.
  30. func MtimeIsWithin(expected time.Time, d time.Duration) oglematchers.Matcher {
  31. return oglematchers.NewMatcher(
  32. func(c interface{}) error { return mtimeIsWithin(c, expected, d) },
  33. fmt.Sprintf("mtime is within %v of %v", d, expected))
  34. }
  35. func mtimeIsWithin(c interface{}, expected time.Time, d time.Duration) error {
  36. fi, ok := c.(os.FileInfo)
  37. if !ok {
  38. return fmt.Errorf("which is of type %v", reflect.TypeOf(c))
  39. }
  40. // Check ModTime().
  41. diff := fi.ModTime().Sub(expected)
  42. absDiff := diff
  43. if absDiff < 0 {
  44. absDiff = -absDiff
  45. }
  46. if !(absDiff < d) {
  47. return fmt.Errorf("which has mtime %v, off by %v", fi.ModTime(), diff)
  48. }
  49. return nil
  50. }
  51. // Match os.FileInfo values that specify a file birth time within the supplied
  52. // radius of the given time. On platforms where there is no birth time
  53. // available, match all os.FileInfo values.
  54. func BirthtimeIsWithin(
  55. expected time.Time,
  56. d time.Duration) oglematchers.Matcher {
  57. return oglematchers.NewMatcher(
  58. func(c interface{}) error { return birthtimeIsWithin(c, expected, d) },
  59. fmt.Sprintf("birthtime is within %v of %v", d, expected))
  60. }
  61. func birthtimeIsWithin(
  62. c interface{},
  63. expected time.Time,
  64. d time.Duration) error {
  65. fi, ok := c.(os.FileInfo)
  66. if !ok {
  67. return fmt.Errorf("which is of type %v", reflect.TypeOf(c))
  68. }
  69. t, ok := extractBirthtime(fi.Sys())
  70. if !ok {
  71. return nil
  72. }
  73. diff := t.Sub(expected)
  74. absDiff := diff
  75. if absDiff < 0 {
  76. absDiff = -absDiff
  77. }
  78. if !(absDiff < d) {
  79. return fmt.Errorf("which has birth time %v, off by %v", t, diff)
  80. }
  81. return nil
  82. }
  83. // Extract time information from the supplied file info. Panic on platforms
  84. // where this is not possible.
  85. func GetTimes(fi os.FileInfo) (atime, ctime, mtime time.Time) {
  86. return getTimes(fi.Sys().(*syscall.Stat_t))
  87. }
  88. // Match os.FileInfo values that specify a number of links equal to the given
  89. // number. On platforms where there is no nlink field available, match all
  90. // os.FileInfo values.
  91. func NlinkIs(expected uint64) oglematchers.Matcher {
  92. return oglematchers.NewMatcher(
  93. func(c interface{}) error { return nlinkIs(c, expected) },
  94. fmt.Sprintf("nlink is %v", expected))
  95. }
  96. func nlinkIs(c interface{}, expected uint64) error {
  97. fi, ok := c.(os.FileInfo)
  98. if !ok {
  99. return fmt.Errorf("which is of type %v", reflect.TypeOf(c))
  100. }
  101. if actual, ok := extractNlink(fi.Sys()); ok && actual != expected {
  102. return fmt.Errorf("which has nlink == %v", actual)
  103. }
  104. return nil
  105. }