github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/go/build/deps_test.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file exercises the import parser but also checks that 6 // some low-level packages do not have new dependencies added. 7 8 package build 9 10 import ( 11 "sort" 12 "testing" 13 ) 14 15 // pkgDeps defines the expected dependencies between packages in 16 // the Go source tree. It is a statement of policy. 17 // Changes should not be made to this map without prior discussion. 18 // 19 // The map contains two kinds of entries: 20 // 1) Lower-case keys are standard import paths and list the 21 // allowed imports in that package. 22 // 2) Upper-case keys define aliases for package sets, which can then 23 // be used as dependencies by other rules. 24 // 25 // DO NOT CHANGE THIS DATA TO FIX BUILDS. 26 // 27 var pkgDeps = map[string][]string{ 28 // L0 is the lowest level, core, nearly unavoidable packages. 29 "errors": {}, 30 "io": {"errors", "sync"}, 31 "runtime": {"unsafe"}, 32 "sync": {"sync/atomic", "unsafe"}, 33 "sync/atomic": {"unsafe"}, 34 "unsafe": {}, 35 36 "L0": { 37 "errors", 38 "io", 39 "runtime", 40 "sync", 41 "sync/atomic", 42 "unsafe", 43 }, 44 45 // L1 adds simple functions and strings processing, 46 // but not Unicode tables. 47 "math": {"unsafe"}, 48 "math/cmplx": {"math"}, 49 "math/rand": {"L0", "math"}, 50 "sort": {}, 51 "strconv": {"L0", "unicode/utf8", "math"}, 52 "unicode/utf16": {}, 53 "unicode/utf8": {}, 54 55 "L1": { 56 "L0", 57 "math", 58 "math/cmplx", 59 "math/rand", 60 "sort", 61 "strconv", 62 "unicode/utf16", 63 "unicode/utf8", 64 }, 65 66 // L2 adds Unicode and strings processing. 67 "bufio": {"L0", "unicode/utf8", "bytes"}, 68 "bytes": {"L0", "unicode", "unicode/utf8"}, 69 "path": {"L0", "unicode/utf8", "strings"}, 70 "strings": {"L0", "unicode", "unicode/utf8"}, 71 "unicode": {}, 72 73 "L2": { 74 "L1", 75 "bufio", 76 "bytes", 77 "path", 78 "strings", 79 "unicode", 80 }, 81 82 // L3 adds reflection and some basic utility packages 83 // and interface definitions, but nothing that makes 84 // system calls. 85 "crypto": {"L2", "hash"}, // interfaces 86 "crypto/cipher": {"L2", "crypto/subtle"}, // interfaces 87 "crypto/subtle": {}, 88 "encoding/base32": {"L2"}, 89 "encoding/base64": {"L2"}, 90 "encoding/binary": {"L2", "reflect"}, 91 "hash": {"L2"}, // interfaces 92 "hash/adler32": {"L2", "hash"}, 93 "hash/crc32": {"L2", "hash"}, 94 "hash/crc64": {"L2", "hash"}, 95 "hash/fnv": {"L2", "hash"}, 96 "image": {"L2", "image/color"}, // interfaces 97 "image/color": {"L2"}, // interfaces 98 "image/color/palette": {"L2", "image/color"}, 99 "reflect": {"L2"}, 100 101 "L3": { 102 "L2", 103 "crypto", 104 "crypto/cipher", 105 "crypto/subtle", 106 "encoding/base32", 107 "encoding/base64", 108 "encoding/binary", 109 "hash", 110 "hash/adler32", 111 "hash/crc32", 112 "hash/crc64", 113 "hash/fnv", 114 "image", 115 "image/color", 116 "image/color/palette", 117 "reflect", 118 }, 119 120 // End of linear dependency definitions. 121 122 // Operating system access. 123 "syscall": {"L0", "unicode/utf16"}, 124 "time": {"L0", "syscall"}, 125 "os": {"L1", "os", "syscall", "time"}, 126 "path/filepath": {"L2", "os", "syscall"}, 127 "io/ioutil": {"L2", "os", "path/filepath", "time"}, 128 "os/exec": {"L2", "os", "syscall"}, 129 "os/signal": {"L2", "os", "syscall"}, 130 131 // OS enables basic operating system functionality, 132 // but not direct use of package syscall, nor os/signal. 133 "OS": { 134 "io/ioutil", 135 "os", 136 "os/exec", 137 "path/filepath", 138 "time", 139 }, 140 141 // Formatted I/O: few dependencies (L1) but we must add reflect. 142 "fmt": {"L1", "os", "reflect"}, 143 "log": {"L1", "os", "fmt", "time"}, 144 145 // Packages used by testing must be low-level (L2+fmt). 146 "regexp": {"L2", "regexp/syntax"}, 147 "regexp/syntax": {"L2"}, 148 "runtime/debug": {"L2", "fmt", "io/ioutil", "os", "time"}, 149 "runtime/pprof": {"L2", "fmt", "text/tabwriter"}, 150 "text/tabwriter": {"L2"}, 151 152 "testing": {"L2", "flag", "fmt", "os", "runtime/pprof", "time"}, 153 "testing/iotest": {"L2", "log"}, 154 "testing/quick": {"L2", "flag", "fmt", "reflect"}, 155 156 // L4 is defined as L3+fmt+log+time, because in general once 157 // you're using L3 packages, use of fmt, log, or time is not a big deal. 158 "L4": { 159 "L3", 160 "fmt", 161 "log", 162 "time", 163 }, 164 165 // Go parser. 166 "go/ast": {"L4", "OS", "go/scanner", "go/token"}, 167 "go/doc": {"L4", "go/ast", "go/token", "regexp", "text/template"}, 168 "go/parser": {"L4", "OS", "go/ast", "go/scanner", "go/token"}, 169 "go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"}, 170 "go/scanner": {"L4", "OS", "go/token"}, 171 "go/token": {"L4"}, 172 173 "GOPARSER": { 174 "go/ast", 175 "go/doc", 176 "go/parser", 177 "go/printer", 178 "go/scanner", 179 "go/token", 180 }, 181 182 // One of a kind. 183 "archive/tar": {"L4", "OS", "syscall"}, 184 "archive/zip": {"L4", "OS", "compress/flate"}, 185 "compress/bzip2": {"L4"}, 186 "compress/flate": {"L4"}, 187 "compress/gzip": {"L4", "compress/flate"}, 188 "compress/lzw": {"L4"}, 189 "compress/zlib": {"L4", "compress/flate"}, 190 "database/sql": {"L4", "container/list", "database/sql/driver"}, 191 "database/sql/driver": {"L4", "time"}, 192 "debug/dwarf": {"L4"}, 193 "debug/elf": {"L4", "OS", "debug/dwarf"}, 194 "debug/gosym": {"L4"}, 195 "debug/macho": {"L4", "OS", "debug/dwarf"}, 196 "debug/pe": {"L4", "OS", "debug/dwarf"}, 197 "encoding": {"L4"}, 198 "encoding/ascii85": {"L4"}, 199 "encoding/asn1": {"L4", "math/big"}, 200 "encoding/csv": {"L4"}, 201 "encoding/gob": {"L4", "OS", "encoding"}, 202 "encoding/hex": {"L4"}, 203 "encoding/json": {"L4", "encoding"}, 204 "encoding/pem": {"L4"}, 205 "encoding/xml": {"L4", "encoding"}, 206 "flag": {"L4", "OS"}, 207 "go/build": {"L4", "OS", "GOPARSER"}, 208 "html": {"L4"}, 209 "image/draw": {"L4"}, 210 "image/gif": {"L4", "compress/lzw", "image/color/palette", "image/draw"}, 211 "image/jpeg": {"L4"}, 212 "image/png": {"L4", "compress/zlib"}, 213 "index/suffixarray": {"L4", "regexp"}, 214 "math/big": {"L4"}, 215 "mime": {"L4", "OS", "syscall"}, 216 "net/url": {"L4"}, 217 "text/scanner": {"L4", "OS"}, 218 "text/template/parse": {"L4"}, 219 220 "html/template": { 221 "L4", "OS", "encoding/json", "html", "text/template", 222 "text/template/parse", 223 }, 224 "text/template": { 225 "L4", "OS", "net/url", "text/template/parse", 226 }, 227 228 // Cgo. 229 "runtime/cgo": {"L0", "C"}, 230 "CGO": {"C", "runtime/cgo"}, 231 232 // Fake entry to satisfy the pseudo-import "C" 233 // that shows up in programs that use cgo. 234 "C": {}, 235 236 // Plan 9 alone needs io/ioutil and os. 237 "os/user": {"L4", "CGO", "io/ioutil", "os", "syscall"}, 238 239 // Basic networking. 240 // Because net must be used by any package that wants to 241 // do networking portably, it must have a small dependency set: just L1+basic os. 242 "net": {"L1", "CGO", "os", "syscall", "time"}, 243 244 // NET enables use of basic network-related packages. 245 "NET": { 246 "net", 247 "mime", 248 "net/textproto", 249 "net/url", 250 }, 251 252 // Uses of networking. 253 "log/syslog": {"L4", "OS", "net"}, 254 "net/mail": {"L4", "NET", "OS"}, 255 "net/textproto": {"L4", "OS", "net"}, 256 257 // Core crypto. 258 "crypto/aes": {"L3"}, 259 "crypto/des": {"L3"}, 260 "crypto/hmac": {"L3"}, 261 "crypto/md5": {"L3"}, 262 "crypto/rc4": {"L3"}, 263 "crypto/sha1": {"L3"}, 264 "crypto/sha256": {"L3"}, 265 "crypto/sha512": {"L3"}, 266 267 "CRYPTO": { 268 "crypto/aes", 269 "crypto/des", 270 "crypto/hmac", 271 "crypto/md5", 272 "crypto/rc4", 273 "crypto/sha1", 274 "crypto/sha256", 275 "crypto/sha512", 276 }, 277 278 // Random byte, number generation. 279 // This would be part of core crypto except that it imports 280 // math/big, which imports fmt. 281 "crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall"}, 282 283 // Mathematical crypto: dependencies on fmt (L4) and math/big. 284 // We could avoid some of the fmt, but math/big imports fmt anyway. 285 "crypto/dsa": {"L4", "CRYPTO", "math/big"}, 286 "crypto/ecdsa": {"L4", "CRYPTO", "crypto/elliptic", "math/big"}, 287 "crypto/elliptic": {"L4", "CRYPTO", "math/big"}, 288 "crypto/rsa": {"L4", "CRYPTO", "crypto/rand", "math/big"}, 289 290 "CRYPTO-MATH": { 291 "CRYPTO", 292 "crypto/dsa", 293 "crypto/ecdsa", 294 "crypto/elliptic", 295 "crypto/rand", 296 "crypto/rsa", 297 "encoding/asn1", 298 "math/big", 299 }, 300 301 // SSL/TLS. 302 "crypto/tls": { 303 "L4", "CRYPTO-MATH", "CGO", "OS", 304 "crypto/x509", "encoding/pem", "net", "syscall", 305 }, 306 "crypto/x509": { 307 "L4", "CRYPTO-MATH", "OS", "CGO", 308 "crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "syscall", 309 }, 310 "crypto/x509/pkix": {"L4", "CRYPTO-MATH"}, 311 312 // Simple net+crypto-aware packages. 313 "mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto"}, 314 "net/smtp": {"L4", "CRYPTO", "NET", "crypto/tls"}, 315 316 // HTTP, kingpin of dependencies. 317 "net/http": { 318 "L4", "NET", "OS", 319 "compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug", 320 }, 321 322 // HTTP-using packages. 323 "expvar": {"L4", "OS", "encoding/json", "net/http"}, 324 "net/http/cgi": {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"}, 325 "net/http/fcgi": {"L4", "NET", "OS", "net/http", "net/http/cgi"}, 326 "net/http/httptest": {"L4", "NET", "OS", "crypto/tls", "flag", "net/http"}, 327 "net/http/httputil": {"L4", "NET", "OS", "net/http"}, 328 "net/http/pprof": {"L4", "OS", "html/template", "net/http", "runtime/pprof"}, 329 "net/rpc": {"L4", "NET", "encoding/gob", "net/http", "text/template"}, 330 "net/rpc/jsonrpc": {"L4", "NET", "encoding/json", "net/rpc"}, 331 } 332 333 // isMacro reports whether p is a package dependency macro 334 // (uppercase name). 335 func isMacro(p string) bool { 336 return 'A' <= p[0] && p[0] <= 'Z' 337 } 338 339 func allowed(pkg string) map[string]bool { 340 m := map[string]bool{} 341 var allow func(string) 342 allow = func(p string) { 343 if m[p] { 344 return 345 } 346 m[p] = true // set even for macros, to avoid loop on cycle 347 348 // Upper-case names are macro-expanded. 349 if isMacro(p) { 350 for _, pp := range pkgDeps[p] { 351 allow(pp) 352 } 353 } 354 } 355 for _, pp := range pkgDeps[pkg] { 356 allow(pp) 357 } 358 return m 359 } 360 361 var bools = []bool{false, true} 362 var geese = []string{"darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "plan9", "windows"} 363 var goarches = []string{"386", "amd64", "arm"} 364 365 type osPkg struct { 366 goos, pkg string 367 } 368 369 // allowedErrors are the operating systems and packages known to contain errors 370 // (currently just "no Go source files") 371 var allowedErrors = map[osPkg]bool{ 372 osPkg{"windows", "log/syslog"}: true, 373 osPkg{"plan9", "log/syslog"}: true, 374 } 375 376 func TestDependencies(t *testing.T) { 377 var all []string 378 379 for k := range pkgDeps { 380 all = append(all, k) 381 } 382 sort.Strings(all) 383 384 ctxt := Default 385 test := func(mustImport bool) { 386 for _, pkg := range all { 387 if isMacro(pkg) { 388 continue 389 } 390 p, err := ctxt.Import(pkg, "", 0) 391 if err != nil { 392 if allowedErrors[osPkg{ctxt.GOOS, pkg}] { 393 continue 394 } 395 if !ctxt.CgoEnabled && pkg == "runtime/cgo" { 396 continue 397 } 398 // Some of the combinations we try might not 399 // be reasonable (like arm,plan9,cgo), so ignore 400 // errors for the auto-generated combinations. 401 if !mustImport { 402 continue 403 } 404 t.Errorf("%s/%s/cgo=%v %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, err) 405 continue 406 } 407 ok := allowed(pkg) 408 var bad []string 409 for _, imp := range p.Imports { 410 if !ok[imp] { 411 bad = append(bad, imp) 412 } 413 } 414 if bad != nil { 415 t.Errorf("%s/%s/cgo=%v unexpected dependency: %s imports %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, pkg, bad) 416 } 417 } 418 } 419 test(true) 420 421 if testing.Short() { 422 t.Logf("skipping other systems") 423 return 424 } 425 426 for _, ctxt.GOOS = range geese { 427 for _, ctxt.GOARCH = range goarches { 428 for _, ctxt.CgoEnabled = range bools { 429 test(false) 430 } 431 } 432 } 433 }