internal.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package internal contains miscellaneous functions and types
  4. // that are internal to the syspolicy packages.
  5. package internal
  6. import (
  7. "bytes"
  8. "github.com/go-json-experiment/json/jsontext"
  9. "tailscale.com/types/lazy"
  10. "tailscale.com/version"
  11. )
  12. // Init facilitates deferred invocation of initializers.
  13. var Init lazy.DeferredInit
  14. // OSForTesting is the operating system override used for testing.
  15. // It follows the same naming convention as [version.OS].
  16. var OSForTesting lazy.SyncValue[string]
  17. // OS is like [version.OS], but supports a test hook.
  18. func OS() string {
  19. return OSForTesting.Get(version.OS)
  20. }
  21. // TB is a subset of testing.TB that we use to set up test helpers.
  22. // It's defined here to avoid pulling in the testing package.
  23. type TB interface {
  24. Helper()
  25. Cleanup(func())
  26. Logf(format string, args ...any)
  27. Error(args ...any)
  28. Errorf(format string, args ...any)
  29. Fatal(args ...any)
  30. Fatalf(format string, args ...any)
  31. }
  32. // EqualJSONForTest compares the JSON in j1 and j2 for semantic equality.
  33. // It returns "", "", true if j1 and j2 are equal. Otherwise, it returns
  34. // indented versions of j1 and j2 and false.
  35. func EqualJSONForTest(tb TB, j1, j2 jsontext.Value) (s1, s2 string, equal bool) {
  36. tb.Helper()
  37. j1 = j1.Clone()
  38. j2 = j2.Clone()
  39. // Canonicalize JSON values for comparison.
  40. if err := j1.Canonicalize(); err != nil {
  41. tb.Error(err)
  42. }
  43. if err := j2.Canonicalize(); err != nil {
  44. tb.Error(err)
  45. }
  46. // Check and return true if the two values are structurally equal.
  47. if bytes.Equal(j1, j2) {
  48. return "", "", true
  49. }
  50. // Otherwise, format the values for display and return false.
  51. if err := j1.Indent("", "\t"); err != nil {
  52. tb.Fatal(err)
  53. }
  54. if err := j2.Indent("", "\t"); err != nil {
  55. tb.Fatal(err)
  56. }
  57. return j1.String(), j2.String(), false
  58. }