testutils.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package testutils
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strings"
  6. "time"
  7. "github.com/docker/docker/api/types/events"
  8. timetypes "github.com/docker/docker/api/types/time"
  9. )
  10. var (
  11. reTimestamp = `(?P<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{9}(:?(:?(:?-|\+)\d{2}:\d{2})|Z))`
  12. reEventType = `(?P<eventType>\w+)`
  13. reAction = `(?P<action>\w+)`
  14. reID = `(?P<id>[^\s]+)`
  15. reAttributes = `(\s\((?P<attributes>[^\)]+)\))?`
  16. reString = fmt.Sprintf(`\A%s\s%s\s%s\s%s%s\z`, reTimestamp, reEventType, reAction, reID, reAttributes)
  17. // eventCliRegexp is a regular expression that matches all possible event outputs in the cli
  18. eventCliRegexp = regexp.MustCompile(reString)
  19. )
  20. // ScanMap turns an event string like the default ones formatted in the cli output
  21. // and turns it into map.
  22. func ScanMap(text string) map[string]string {
  23. matches := eventCliRegexp.FindAllStringSubmatch(text, -1)
  24. md := map[string]string{}
  25. if len(matches) == 0 {
  26. return md
  27. }
  28. names := eventCliRegexp.SubexpNames()
  29. for i, n := range matches[0] {
  30. md[names[i]] = n
  31. }
  32. return md
  33. }
  34. // Scan turns an event string like the default ones formatted in the cli output
  35. // and turns it into an event message.
  36. func Scan(text string) (*events.Message, error) {
  37. md := ScanMap(text)
  38. if len(md) == 0 {
  39. return nil, fmt.Errorf("text is not an event: %s", text)
  40. }
  41. f, err := timetypes.GetTimestamp(md["timestamp"], time.Now())
  42. if err != nil {
  43. return nil, err
  44. }
  45. t, tn, err := timetypes.ParseTimestamps(f, -1)
  46. if err != nil {
  47. return nil, err
  48. }
  49. attrs := make(map[string]string)
  50. for _, a := range strings.SplitN(md["attributes"], ", ", -1) {
  51. kv := strings.SplitN(a, "=", 2)
  52. attrs[kv[0]] = kv[1]
  53. }
  54. tu := time.Unix(t, tn)
  55. return &events.Message{
  56. Time: t,
  57. TimeNano: tu.UnixNano(),
  58. Type: md["eventType"],
  59. Action: md["action"],
  60. Actor: events.Actor{
  61. ID: md["id"],
  62. Attributes: attrs,
  63. },
  64. }, nil
  65. }