deps_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package main
  4. import (
  5. "maps"
  6. "slices"
  7. "strings"
  8. "testing"
  9. "tailscale.com/feature/featuretags"
  10. "tailscale.com/tstest/deptest"
  11. )
  12. func TestOmitSSH(t *testing.T) {
  13. const msg = "unexpected with ts_omit_ssh"
  14. deptest.DepChecker{
  15. GOOS: "linux",
  16. GOARCH: "amd64",
  17. Tags: "ts_omit_ssh,ts_include_cli",
  18. BadDeps: map[string]string{
  19. "golang.org/x/crypto/ssh": msg,
  20. "tailscale.com/ssh/tailssh": msg,
  21. "tailscale.com/sessionrecording": msg,
  22. "github.com/anmitsu/go-shlex": msg,
  23. "github.com/creack/pty": msg,
  24. "github.com/kr/fs": msg,
  25. "github.com/pkg/sftp": msg,
  26. "github.com/u-root/u-root/pkg/termios": msg,
  27. "tempfork/gliderlabs/ssh": msg,
  28. },
  29. }.Check(t)
  30. }
  31. func TestOmitSyspolicy(t *testing.T) {
  32. const msg = "unexpected syspolicy usage with ts_omit_syspolicy"
  33. deptest.DepChecker{
  34. GOOS: "linux",
  35. GOARCH: "amd64",
  36. Tags: "ts_omit_syspolicy,ts_include_cli",
  37. BadDeps: map[string]string{
  38. "tailscale.com/util/syspolicy": msg,
  39. "tailscale.com/util/syspolicy/setting": msg,
  40. "tailscale.com/util/syspolicy/rsop": msg,
  41. },
  42. }.Check(t)
  43. }
  44. func TestOmitLocalClient(t *testing.T) {
  45. deptest.DepChecker{
  46. GOOS: "linux",
  47. GOARCH: "amd64",
  48. Tags: "ts_omit_webclient,ts_omit_relayserver,ts_omit_oauthkey,ts_omit_acme",
  49. BadDeps: map[string]string{
  50. "tailscale.com/client/local": "unexpected",
  51. },
  52. }.Check(t)
  53. }
  54. // Test that we can build a binary without reflect.MethodByName.
  55. // See https://github.com/tailscale/tailscale/issues/17063
  56. func TestOmitReflectThings(t *testing.T) {
  57. deptest.DepChecker{
  58. GOOS: "linux",
  59. GOARCH: "amd64",
  60. Tags: "ts_include_cli,ts_omit_systray,ts_omit_debugeventbus,ts_omit_webclient",
  61. BadDeps: map[string]string{
  62. "text/template": "unexpected text/template usage",
  63. "html/template": "unexpected text/template usage",
  64. },
  65. OnDep: func(dep string) {
  66. if strings.Contains(dep, "systray") {
  67. t.Errorf("unexpected systray dep %q", dep)
  68. }
  69. },
  70. }.Check(t)
  71. }
  72. func TestOmitDrive(t *testing.T) {
  73. deptest.DepChecker{
  74. GOOS: "linux",
  75. GOARCH: "amd64",
  76. Tags: "ts_omit_drive,ts_include_cli",
  77. OnDep: func(dep string) {
  78. if strings.Contains(dep, "driveimpl") {
  79. t.Errorf("unexpected dep with ts_omit_drive: %q", dep)
  80. }
  81. if strings.Contains(dep, "webdav") {
  82. t.Errorf("unexpected dep with ts_omit_drive: %q", dep)
  83. }
  84. },
  85. }.Check(t)
  86. }
  87. func TestOmitPortmapper(t *testing.T) {
  88. deptest.DepChecker{
  89. GOOS: "linux",
  90. GOARCH: "amd64",
  91. Tags: "ts_omit_portmapper,ts_include_cli,ts_omit_debugportmapper",
  92. OnDep: func(dep string) {
  93. if dep == "tailscale.com/net/portmapper" {
  94. t.Errorf("unexpected dep with ts_omit_portmapper: %q", dep)
  95. return
  96. }
  97. if strings.Contains(dep, "goupnp") || strings.Contains(dep, "/soap") ||
  98. strings.Contains(dep, "internetgateway2") {
  99. t.Errorf("unexpected dep with ts_omit_portmapper: %q", dep)
  100. }
  101. },
  102. }.Check(t)
  103. }
  104. func TestOmitACME(t *testing.T) {
  105. deptest.DepChecker{
  106. GOOS: "linux",
  107. GOARCH: "amd64",
  108. Tags: "ts_omit_acme,ts_include_cli",
  109. OnDep: func(dep string) {
  110. if strings.Contains(dep, "/acme") {
  111. t.Errorf("unexpected dep with ts_omit_acme: %q", dep)
  112. }
  113. },
  114. }.Check(t)
  115. }
  116. func TestOmitCaptivePortal(t *testing.T) {
  117. deptest.DepChecker{
  118. GOOS: "linux",
  119. GOARCH: "amd64",
  120. Tags: "ts_omit_captiveportal,ts_include_cli",
  121. OnDep: func(dep string) {
  122. if strings.Contains(dep, "captive") {
  123. t.Errorf("unexpected dep with ts_omit_captiveportal: %q", dep)
  124. }
  125. },
  126. }.Check(t)
  127. }
  128. func TestOmitAuth(t *testing.T) {
  129. deptest.DepChecker{
  130. GOOS: "linux",
  131. GOARCH: "amd64",
  132. Tags: "ts_omit_oauthkey,ts_omit_identityfederation,ts_include_cli",
  133. OnDep: func(dep string) {
  134. if strings.HasPrefix(dep, "golang.org/x/oauth2") {
  135. t.Errorf("unexpected oauth2 dep: %q", dep)
  136. }
  137. },
  138. }.Check(t)
  139. }
  140. func TestOmitOutboundProxy(t *testing.T) {
  141. deptest.DepChecker{
  142. GOOS: "linux",
  143. GOARCH: "amd64",
  144. Tags: "ts_omit_outboundproxy,ts_include_cli",
  145. OnDep: func(dep string) {
  146. if strings.Contains(dep, "socks5") || strings.Contains(dep, "proxymux") {
  147. t.Errorf("unexpected dep with ts_omit_outboundproxy: %q", dep)
  148. }
  149. },
  150. }.Check(t)
  151. }
  152. func TestOmitDBus(t *testing.T) {
  153. deptest.DepChecker{
  154. GOOS: "linux",
  155. GOARCH: "amd64",
  156. Tags: "ts_omit_networkmanager,ts_omit_dbus,ts_omit_resolved,ts_omit_systray,ts_omit_ssh,ts_include_cli",
  157. OnDep: func(dep string) {
  158. if strings.Contains(dep, "dbus") {
  159. t.Errorf("unexpected DBus dep: %q", dep)
  160. }
  161. },
  162. }.Check(t)
  163. }
  164. func TestNetstack(t *testing.T) {
  165. deptest.DepChecker{
  166. GOOS: "linux",
  167. GOARCH: "amd64",
  168. Tags: "ts_omit_gro,ts_omit_netstack,ts_omit_outboundproxy,ts_omit_serve,ts_omit_ssh,ts_omit_webclient,ts_omit_tap",
  169. OnDep: func(dep string) {
  170. if strings.Contains(dep, "gvisor") {
  171. t.Errorf("unexpected gvisor dep: %q", dep)
  172. }
  173. },
  174. }.Check(t)
  175. }
  176. func TestOmitPortlist(t *testing.T) {
  177. deptest.DepChecker{
  178. GOOS: "linux",
  179. GOARCH: "amd64",
  180. Tags: "ts_omit_portlist,ts_include_cli",
  181. OnDep: func(dep string) {
  182. if strings.Contains(dep, "portlist") {
  183. t.Errorf("unexpected dep: %q", dep)
  184. }
  185. },
  186. }.Check(t)
  187. }
  188. func TestOmitGRO(t *testing.T) {
  189. deptest.DepChecker{
  190. GOOS: "linux",
  191. GOARCH: "amd64",
  192. Tags: "ts_omit_gro,ts_include_cli",
  193. BadDeps: map[string]string{
  194. "gvisor.dev/gvisor/pkg/tcpip/stack/gro": "unexpected dep with ts_omit_gro",
  195. },
  196. }.Check(t)
  197. }
  198. func TestOmitUseProxy(t *testing.T) {
  199. deptest.DepChecker{
  200. GOOS: "linux",
  201. GOARCH: "amd64",
  202. Tags: "ts_omit_useproxy,ts_include_cli",
  203. OnDep: func(dep string) {
  204. if strings.Contains(dep, "tshttproxy") {
  205. t.Errorf("unexpected dep: %q", dep)
  206. }
  207. },
  208. }.Check(t)
  209. }
  210. func minTags() string {
  211. var tags []string
  212. for _, f := range slices.Sorted(maps.Keys(featuretags.Features)) {
  213. if f.IsOmittable() {
  214. tags = append(tags, f.OmitTag())
  215. }
  216. }
  217. return strings.Join(tags, ",")
  218. }
  219. func TestMinTailscaledNoCLI(t *testing.T) {
  220. badSubstrs := []string{
  221. "cbor",
  222. "regexp",
  223. "golang.org/x/net/proxy",
  224. "internal/socks",
  225. "github.com/tailscale/peercred",
  226. "tailscale.com/types/netlogtype",
  227. "deephash",
  228. "util/hashx",
  229. }
  230. deptest.DepChecker{
  231. GOOS: "linux",
  232. GOARCH: "amd64",
  233. Tags: minTags(),
  234. OnDep: func(dep string) {
  235. for _, bad := range badSubstrs {
  236. if strings.Contains(dep, bad) {
  237. t.Errorf("unexpected dep: %q", dep)
  238. }
  239. }
  240. },
  241. }.Check(t)
  242. }
  243. func TestMinTailscaledWithCLI(t *testing.T) {
  244. badSubstrs := []string{
  245. "cbor",
  246. "hujson",
  247. "pprof",
  248. "multierr", // https://github.com/tailscale/tailscale/pull/17379
  249. "tailscale.com/metrics",
  250. "tailscale.com/tsweb/varz",
  251. "dirwalk",
  252. "deephash",
  253. "util/hashx",
  254. }
  255. deptest.DepChecker{
  256. GOOS: "linux",
  257. GOARCH: "amd64",
  258. Tags: minTags() + ",ts_include_cli",
  259. OnDep: func(dep string) {
  260. for _, bad := range badSubstrs {
  261. if strings.Contains(dep, bad) {
  262. t.Errorf("unexpected dep: %q", dep)
  263. }
  264. }
  265. },
  266. BadDeps: map[string]string{
  267. "golang.org/x/net/http2": "unexpected x/net/http2 dep; tailscale/tailscale#17305",
  268. "expvar": "unexpected expvar dep",
  269. "github.com/mdlayher/genetlink": "unexpected genetlink dep",
  270. },
  271. }.Check(t)
  272. }