tour: fix go.mod module path

The supporting packages (pic, reader, tree, wc) are still
in golang.org/x/tour, so delete these copies.

Fix the remaining references in local.go to use
golang.org/x/website/tour instead of golang.org/x/tour
to find the content files.

While we are here, make go test ./... considerably faster
by parallelizing TestContent.

For golang/go#46501.

Change-Id: Ia80161830f5f2f87fb6e39a0ee39c4b176fb425b
Reviewed-on: https://go-review.googlesource.com/c/website/+/324395
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Website-Publish: Russ Cox <rsc@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/tour/content/content_test.go b/tour/content/content_test.go
index 4c0ff2a..64b8136 100644
--- a/tour/content/content_test.go
+++ b/tour/content/content_test.go
@@ -14,6 +14,9 @@
 	"path/filepath"
 	"strings"
 	"testing"
+
+	// Keep golang.org/x/tour in our go.mod require list for use during test.
+	_ "golang.org/x/tour/wc"
 )
 
 // Test that all the .go files inside the content file build
@@ -38,9 +41,12 @@
 		if filepath.Base(path) == "content_test.go" {
 			return nil
 		}
-		if err := testSnippet(t, path, scratch); err != nil {
-			t.Errorf("%v: %v", path, err)
-		}
+		t.Run(path, func(t *testing.T) {
+			t.Parallel()
+			if err := testSnippet(t, path, scratch); err != nil {
+				t.Errorf("%v: %v", path, err)
+			}
+		})
 		return nil
 	})
 	if err != nil {
diff --git a/tour/go.mod b/tour/go.mod
index ceb57a7..a1d1ebf 100644
--- a/tour/go.mod
+++ b/tour/go.mod
@@ -1,5 +1,8 @@
-module golang.org/x/tour
+module golang.org/x/website/tour
 
 go 1.11
 
-require golang.org/x/tools v0.1.3-0.20210525215409-a3eb095d6aee
+require (
+	golang.org/x/tools v0.1.3-0.20210525215409-a3eb095d6aee
+	golang.org/x/tour v0.1.0
+)
diff --git a/tour/go.sum b/tour/go.sum
index f2eedd1..0931281 100644
--- a/tour/go.sum
+++ b/tour/go.sum
@@ -23,6 +23,8 @@
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.3-0.20210525215409-a3eb095d6aee h1:qoXIhA/wpnHg2z8RiA/rZb66+iiULmKyO9olVAU+GfU=
 golang.org/x/tools v0.1.3-0.20210525215409-a3eb095d6aee/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tour v0.1.0 h1:OWzbINRoGf1wwBhKdFDpYwM88NM0d1SL/Nj6PagS6YE=
+golang.org/x/tour v0.1.0/go.mod h1:DUZC6G8mR1AXgXy73r8qt/G5RsefKIlSj6jBMc8b9Wc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
diff --git a/tour/gotour/main.go b/tour/gotour/main.go
deleted file mode 100644
index b0b2d50..0000000
--- a/tour/gotour/main.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"io"
-	"os"
-)
-
-func main() {
-	io.WriteString(os.Stderr, "golang.org/x/tour/gotour has moved to golang.org/x/tour\n")
-	os.Exit(1)
-}
diff --git a/tour/local.go b/tour/local.go
index 076cf94..9d4692d 100644
--- a/tour/local.go
+++ b/tour/local.go
@@ -23,11 +23,6 @@
 	"time"
 
 	"golang.org/x/tools/playground/socket"
-
-	// Imports so that go build/install automatically installs them.
-	_ "golang.org/x/tour/pic"
-	_ "golang.org/x/tour/tree"
-	_ "golang.org/x/tour/wc"
 )
 
 const (
@@ -58,20 +53,20 @@
 //
 // TODO: Delete after Go 1.17 is out and we can just use embed; see CL 291849.
 func findRoot() (string, bool) {
-	// Try finding the golang.org/x/tour package in the
+	// Try finding the golang.org/x/website/tour package in the
 	// legacy GOPATH mode workspace or in build list.
-	p, err := build.Import("golang.org/x/tour", "", build.FindOnly)
+	p, err := build.Import("golang.org/x/website/tour", "", build.FindOnly)
 	if err == nil && isRoot(p.Dir) {
 		return p.Dir, true
 	}
 	// If that didn't work, perhaps we're not inside any module
 	// and the binary was built in module mode (e.g., 'go install
-	// golang.org/x/tour@latest' or 'go get golang.org/x/tour'
+	// golang.org/x/website/tour@latest' or 'go get golang.org/x/website/tour'
 	// outside a module).
 	// In that's the case, find out what version it is,
 	// and access its content from the module cache.
 	if info, ok := debug.ReadBuildInfo(); ok &&
-		info.Main.Path == "golang.org/x/tour" &&
+		info.Main.Path == "golang.org/x/website/tour" &&
 		info.Main.Replace == nil &&
 		info.Main.Version != "(devel)" {
 		// Make some assumptions for brevity:
@@ -80,7 +75,7 @@
 		// • the version isn't "(devel)"
 		// They should hold for the use cases we care about, until this
 		// entire mechanism is obsoleted by file embedding.
-		out, execError := exec.Command("go", "mod", "download", "-json", "--", "golang.org/x/tour@"+info.Main.Version).Output()
+		out, execError := exec.Command("go", "mod", "download", "-json", "--", "golang.org/x/website/tour@"+info.Main.Version).Output()
 		var tourRoot struct{ Dir string }
 		jsonError := json.Unmarshal(out, &tourRoot)
 		if execError == nil && jsonError == nil && isRoot(tourRoot.Dir) {
diff --git a/tour/pic/pic.go b/tour/pic/pic.go
deleted file mode 100644
index f60ba0e..0000000
--- a/tour/pic/pic.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pic implements functions that
-// display pictures on the Go playground.
-package pic // import "golang.org/x/tour/pic"
-
-import (
-	"bufio"
-	"encoding/base64"
-	"image"
-	"image/png"
-	"io"
-	"os"
-)
-
-// Show displays a picture defined by the function f
-// when executed on the Go Playground.
-//
-// f should return a slice of length dy,
-// each element of which is a slice of dx
-// 8-bit unsigned int. The integers are
-// interpreted as bluescale values,
-// where the value 0 means full blue,
-// and the value 255 means full white.
-func Show(f func(dx, dy int) [][]uint8) {
-	const (
-		dx = 256
-		dy = 256
-	)
-	data := f(dx, dy)
-	m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
-	for y := 0; y < dy; y++ {
-		for x := 0; x < dx; x++ {
-			v := data[y][x]
-			i := y*m.Stride + x*4
-			m.Pix[i] = v
-			m.Pix[i+1] = v
-			m.Pix[i+2] = 255
-			m.Pix[i+3] = 255
-		}
-	}
-	ShowImage(m)
-}
-
-// ShowImage displays the image m
-// when executed on the Go Playground.
-func ShowImage(m image.Image) {
-	w := bufio.NewWriter(os.Stdout)
-	defer w.Flush()
-	io.WriteString(w, "IMAGE:")
-	b64 := base64.NewEncoder(base64.StdEncoding, w)
-	err := (&png.Encoder{CompressionLevel: png.BestCompression}).Encode(b64, m)
-	if err != nil {
-		panic(err)
-	}
-	b64.Close()
-	io.WriteString(w, "\n")
-}
diff --git a/tour/pic/pic_test.go b/tour/pic/pic_test.go
deleted file mode 100644
index 0e8ccf5..0000000
--- a/tour/pic/pic_test.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pic_test
-
-import "golang.org/x/tour/pic"
-
-func ExampleShow() {
-	f := func(dx, dy int) [][]uint8 {
-		ss := make([][]uint8, dy)
-		for y := 0; y < dy; y++ {
-			s := make([]uint8, dx)
-			for x := 0; x < dx; x++ {
-				s[x] = uint8((x + y) / 2)
-			}
-			ss[y] = s
-		}
-		return ss
-	}
-
-	pic.Show(f)
-
-	// Output:
-	// IMAGE:iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACaUlEQVR42uzVMRGAAAzAwLSHf8tgAAf95QVkyVNvNRN50FWBl10V6ABa0AFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIB6ADqEAHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdAA6gBZ0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIB6AAq0AFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgA6gAh2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADyxy8AAP//YSoDD5pLB7MAAAAASUVORK5CYII=
-}
diff --git a/tour/reader/validate.go b/tour/reader/validate.go
deleted file mode 100644
index 5d3a2c2..0000000
--- a/tour/reader/validate.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package reader // import "golang.org/x/tour/reader"
-
-import (
-	"fmt"
-	"io"
-	"os"
-)
-
-func Validate(r io.Reader) {
-	b := make([]byte, 1024, 2048)
-	i, o := 0, 0
-	for ; i < 1<<20 && o < 1<<20; i++ { // test 1mb
-		n, err := r.Read(b)
-		for i, v := range b[:n] {
-			if v != 'A' {
-				fmt.Fprintf(os.Stderr, "got byte %x at offset %v, want 'A'\n", v, o+i)
-				return
-			}
-		}
-		o += n
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "read error: %v\n", err)
-			return
-		}
-	}
-	if o == 0 {
-		fmt.Fprintf(os.Stderr, "read zero bytes after %d Read calls\n", i)
-		return
-	}
-	fmt.Println("OK!")
-}
diff --git a/tour/tour.go b/tour/tour.go
index b27fc50..3534d41 100644
--- a/tour/tour.go
+++ b/tour/tour.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package main // import "golang.org/x/tour"
+package main // import "golang.org/x/website/tour"
 
 import (
 	"bytes"
diff --git a/tour/tree/tree.go b/tour/tree/tree.go
deleted file mode 100644
index 4dfa76c..0000000
--- a/tour/tree/tree.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tree // import "golang.org/x/tour/tree"
-
-import (
-	"fmt"
-	"math/rand"
-)
-
-// A Tree is a binary tree with integer values.
-type Tree struct {
-	Left  *Tree
-	Value int
-	Right *Tree
-}
-
-// New returns a new, random binary tree holding the values k, 2k, ..., 10k.
-func New(k int) *Tree {
-	var t *Tree
-	for _, v := range rand.Perm(10) {
-		t = insert(t, (1+v)*k)
-	}
-	return t
-}
-
-func insert(t *Tree, v int) *Tree {
-	if t == nil {
-		return &Tree{nil, v, nil}
-	}
-	if v < t.Value {
-		t.Left = insert(t.Left, v)
-	} else {
-		t.Right = insert(t.Right, v)
-	}
-	return t
-}
-
-func (t *Tree) String() string {
-	if t == nil {
-		return "()"
-	}
-	s := ""
-	if t.Left != nil {
-		s += t.Left.String() + " "
-	}
-	s += fmt.Sprint(t.Value)
-	if t.Right != nil {
-		s += " " + t.Right.String()
-	}
-	return "(" + s + ")"
-}
diff --git a/tour/wc/wc.go b/tour/wc/wc.go
deleted file mode 100644
index 94acf1a..0000000
--- a/tour/wc/wc.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package wc // import "golang.org/x/tour/wc"
-
-import "fmt"
-
-// Test runs a test suite against f.
-func Test(f func(string) map[string]int) {
-	ok := true
-	for _, c := range testCases {
-		got := f(c.in)
-		if len(c.want) != len(got) {
-			ok = false
-		} else {
-			for k := range c.want {
-				if c.want[k] != got[k] {
-					ok = false
-				}
-			}
-		}
-		if !ok {
-			fmt.Printf("FAIL\n f(%q) =\n  %#v\n want:\n  %#v",
-				c.in, got, c.want)
-			break
-		}
-		fmt.Printf("PASS\n f(%q) = \n  %#v\n", c.in, got)
-	}
-}
-
-var testCases = []struct {
-	in   string
-	want map[string]int
-}{
-	{"I am learning Go!", map[string]int{
-		"I": 1, "am": 1, "learning": 1, "Go!": 1,
-	}},
-	{"The quick brown fox jumped over the lazy dog.", map[string]int{
-		"The": 1, "quick": 1, "brown": 1, "fox": 1, "jumped": 1,
-		"over": 1, "the": 1, "lazy": 1, "dog.": 1,
-	}},
-	{"I ate a donut. Then I ate another donut.", map[string]int{
-		"I": 2, "ate": 2, "a": 1, "donut.": 2, "Then": 1, "another": 1,
-	}},
-	{"A man a plan a canal panama.", map[string]int{
-		"A": 1, "man": 1, "a": 2, "plan": 1, "canal": 1, "panama.": 1,
-	}},
-}