github.com/AndrienkoAleksandr/go@v0.0.19/src/intern/coverage/pods/pods_test.go (about) 1 // Copyright 2022 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 package pods_test 6 7 import ( 8 "crypto/md5" 9 "fmt" 10 "internal/coverage" 11 "internal/coverage/pods" 12 "os" 13 "path/filepath" 14 "runtime" 15 "testing" 16 ) 17 18 func TestPodCollection(t *testing.T) { 19 //testenv.MustHaveGoBuild(t) 20 21 mkdir := func(d string, perm os.FileMode) string { 22 dp := filepath.Join(t.TempDir(), d) 23 if err := os.Mkdir(dp, perm); err != nil { 24 t.Fatal(err) 25 } 26 return dp 27 } 28 29 mkfile := func(d string, fn string) string { 30 fp := filepath.Join(d, fn) 31 if err := os.WriteFile(fp, []byte("foo"), 0666); err != nil { 32 t.Fatal(err) 33 } 34 return fp 35 } 36 37 mkmeta := func(dir string, tag string) string { 38 hash := md5.Sum([]byte(tag)) 39 fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, hash) 40 return mkfile(dir, fn) 41 } 42 43 mkcounter := func(dir string, tag string, nt int, pid int) string { 44 hash := md5.Sum([]byte(tag)) 45 fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, hash, pid, nt) 46 return mkfile(dir, fn) 47 } 48 49 trim := func(path string) string { 50 b := filepath.Base(path) 51 d := filepath.Dir(path) 52 db := filepath.Base(d) 53 return db + "/" + b 54 } 55 56 podToString := func(p pods.Pod) string { 57 rv := trim(p.MetaFile) + " [\n" 58 for k, df := range p.CounterDataFiles { 59 rv += trim(df) 60 if p.Origins != nil { 61 rv += fmt.Sprintf(" o:%d", p.Origins[k]) 62 } 63 rv += "\n" 64 } 65 return rv + "]" 66 } 67 68 // Create a couple of directories. 69 o1 := mkdir("o1", 0777) 70 o2 := mkdir("o2", 0777) 71 72 // Add some random files (not coverage related) 73 mkfile(o1, "blah.txt") 74 mkfile(o1, "something.exe") 75 76 // Add a meta-data file with two counter files to first dir. 77 mkmeta(o1, "m1") 78 mkcounter(o1, "m1", 1, 42) 79 mkcounter(o1, "m1", 2, 41) 80 mkcounter(o1, "m1", 2, 40) 81 82 // Add a counter file with no associated meta file. 83 mkcounter(o1, "orphan", 9, 39) 84 85 // Add a meta-data file with three counter files to second dir. 86 mkmeta(o2, "m2") 87 mkcounter(o2, "m2", 1, 38) 88 mkcounter(o2, "m2", 2, 37) 89 mkcounter(o2, "m2", 3, 36) 90 91 // Add a duplicate of the first meta-file and a corresponding 92 // counter file to the second dir. This is intended to capture 93 // the scenario where we have two different runs of the same 94 // coverage-instrumented binary, but with the output files 95 // sent to separate directories. 96 mkmeta(o2, "m1") 97 mkcounter(o2, "m1", 11, 35) 98 99 // Collect pods. 100 podlist, err := pods.CollectPods([]string{o1, o2}, true) 101 if err != nil { 102 t.Fatal(err) 103 } 104 105 // Verify pods 106 if len(podlist) != 2 { 107 t.Fatalf("expected 2 pods got %d pods", len(podlist)) 108 } 109 110 for k, p := range podlist { 111 t.Logf("%d: mf=%s\n", k, p.MetaFile) 112 } 113 114 expected := []string{ 115 `o1/covmeta.ae7be26cdaa742ca148068d5ac90eaca [ 116 o1/covcounters.ae7be26cdaa742ca148068d5ac90eaca.40.2 o:0 117 o1/covcounters.ae7be26cdaa742ca148068d5ac90eaca.41.2 o:0 118 o1/covcounters.ae7be26cdaa742ca148068d5ac90eaca.42.1 o:0 119 o2/covcounters.ae7be26cdaa742ca148068d5ac90eaca.35.11 o:1 120 ]`, 121 `o2/covmeta.aaf2f89992379705dac844c0a2a1d45f [ 122 o2/covcounters.aaf2f89992379705dac844c0a2a1d45f.36.3 o:1 123 o2/covcounters.aaf2f89992379705dac844c0a2a1d45f.37.2 o:1 124 o2/covcounters.aaf2f89992379705dac844c0a2a1d45f.38.1 o:1 125 ]`, 126 } 127 for k, exp := range expected { 128 got := podToString(podlist[k]) 129 if exp != got { 130 t.Errorf("pod %d: expected:\n%s\ngot:\n%s", k, exp, got) 131 } 132 } 133 134 // Check handling of bad/unreadable dir. 135 if runtime.GOOS == "linux" { 136 dbad := "/dev/null" 137 _, err = pods.CollectPods([]string{dbad}, true) 138 if err == nil { 139 t.Errorf("executed error due to unreadable dir") 140 } 141 } 142 }