Switch testutil to go-cmp
Remove a dependency by using go-cmp for `testutil.CollectAndCompare()`.
Note that the string output of `cmp.Diff()` is non-stable, so users
depending on stable `error` strings will nolonger work.
Signed-off-by: SuperQ <[email protected]>
diff --git a/NOTICE b/NOTICE
index ba89c57..b9cc55a 100644
--- a/NOTICE
+++ b/NOTICE
@@ -16,8 +16,3 @@
http://github.com/golang/protobuf/
Copyright 2010 The Go Authors
See source code for license details.
-
-diff - a pretty-printed complete of a Go data structure
-https://github.com/kylelemons/godebug
-Copyright 2013 Google Inc. All rights reserved.
-See source code for license details.
diff --git a/prometheus/testutil/diff/diff.go b/prometheus/testutil/diff/diff.go
deleted file mode 100644
index b886256..0000000
--- a/prometheus/testutil/diff/diff.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2013 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// The code in this package is copy/paste to avoid a dependency. Hence this file
-// carries the copyright of the original repo.
-// https://github.com/kylelemons/godebug/tree/v1.1.0/diff
-//
-// Package diff implements a linewise diff algorithm.
-package diff
-
-import (
- "fmt"
- "strings"
-)
-
-// Chunk represents a piece of the diff. A chunk will not have both added and
-// deleted lines. Equal lines are always after any added or deleted lines.
-// A Chunk may or may not have any lines in it, especially for the first or last
-// chunk in a computation.
-type Chunk struct {
- Added []string
- Deleted []string
- Equal []string
-}
-
-func (c *Chunk) empty() bool {
- return len(c.Added) == 0 && len(c.Deleted) == 0 && len(c.Equal) == 0
-}
-
-// Diff returns a string containing a line-by-line unified diff of the linewise
-// changes required to make A into B. Each line is prefixed with '+', '-', or
-// ' ' to indicate if it should be added, removed, or is correct respectively.
-func Diff(A, B string) string {
- aLines := strings.Split(A, "\n")
- bLines := strings.Split(B, "\n")
- return Render(DiffChunks(aLines, bLines))
-}
-
-// Render renders the slice of chunks into a representation that prefixes
-// the lines with '+', '-', or ' ' depending on whether the line was added,
-// removed, or equal (respectively).
-func Render(chunks []Chunk) string {
- buf := new(strings.Builder)
- for _, c := range chunks {
- for _, line := range c.Added {
- fmt.Fprintf(buf, "+%s\n", line)
- }
- for _, line := range c.Deleted {
- fmt.Fprintf(buf, "-%s\n", line)
- }
- for _, line := range c.Equal {
- fmt.Fprintf(buf, " %s\n", line)
- }
- }
- return strings.TrimRight(buf.String(), "\n")
-}
-
-// DiffChunks uses an O(D(N+M)) shortest-edit-script algorithm
-// to compute the edits required from A to B and returns the
-// edit chunks.
-func DiffChunks(a, b []string) []Chunk {
- // algorithm: http://www.xmailserver.org/diff2.pdf
-
- // We'll need these quantities a lot.
- alen, blen := len(a), len(b) // M, N
-
- // At most, it will require len(a) deletions and len(b) additions
- // to transform a into b.
- maxPath := alen + blen // MAX
- if maxPath == 0 {
- // degenerate case: two empty lists are the same
- return nil
- }
-
- // Store the endpoint of the path for diagonals.
- // We store only the a index, because the b index on any diagonal
- // (which we know during the loop below) is aidx-diag.
- // endpoint[maxPath] represents the 0 diagonal.
- //
- // Stated differently:
- // endpoint[d] contains the aidx of a furthest reaching path in diagonal d
- endpoint := make([]int, 2*maxPath+1) // V
-
- saved := make([][]int, 0, 8) // Vs
- save := func() {
- dup := make([]int, len(endpoint))
- copy(dup, endpoint)
- saved = append(saved, dup)
- }
-
- var editDistance int // D
-dLoop:
- for editDistance = 0; editDistance <= maxPath; editDistance++ {
- // The 0 diag(onal) represents equality of a and b. Each diagonal to
- // the left is numbered one lower, to the right is one higher, from
- // -alen to +blen. Negative diagonals favor differences from a,
- // positive diagonals favor differences from b. The edit distance to a
- // diagonal d cannot be shorter than d itself.
- //
- // The iterations of this loop cover either odds or evens, but not both,
- // If odd indices are inputs, even indices are outputs and vice versa.
- for diag := -editDistance; diag <= editDistance; diag += 2 { // k
- var aidx int // x
- switch {
- case diag == -editDistance:
- // This is a new diagonal; copy from previous iter
- aidx = endpoint[maxPath-editDistance+1] + 0
- case diag == editDistance:
- // This is a new diagonal; copy from previous iter
- aidx = endpoint[maxPath+editDistance-1] + 1
- case endpoint[maxPath+diag+1] > endpoint[maxPath+diag-1]:
- // diagonal d+1 was farther along, so use that
- aidx = endpoint[maxPath+diag+1] + 0
- default:
- // diagonal d-1 was farther (or the same), so use that
- aidx = endpoint[maxPath+diag-1] + 1
- }
- // On diagonal d, we can compute bidx from aidx.
- bidx := aidx - diag // y
- // See how far we can go on this diagonal before we find a difference.
- for aidx < alen && bidx < blen && a[aidx] == b[bidx] {
- aidx++
- bidx++
- }
- // Store the end of the current edit chain.
- endpoint[maxPath+diag] = aidx
- // If we've found the end of both inputs, we're done!
- if aidx >= alen && bidx >= blen {
- save() // save the final path
- break dLoop
- }
- }
- save() // save the current path
- }
- if editDistance == 0 {
- return nil
- }
- chunks := make([]Chunk, editDistance+1)
-
- x, y := alen, blen
- for d := editDistance; d > 0; d-- {
- endpoint := saved[d]
- diag := x - y
- insert := diag == -d || (diag != d && endpoint[maxPath+diag-1] < endpoint[maxPath+diag+1])
-
- x1 := endpoint[maxPath+diag]
- var x0, xM, kk int
- if insert {
- kk = diag + 1
- x0 = endpoint[maxPath+kk]
- xM = x0
- } else {
- kk = diag - 1
- x0 = endpoint[maxPath+kk]
- xM = x0 + 1
- }
- y0 := x0 - kk
-
- var c Chunk
- if insert {
- c.Added = b[y0:][:1]
- } else {
- c.Deleted = a[x0:][:1]
- }
- if xM < x1 {
- c.Equal = a[xM:][:x1-xM]
- }
-
- x, y = x0, y0
- chunks[d] = c
- }
- if x > 0 {
- chunks[0].Equal = a[:x]
- }
- if chunks[0].empty() {
- chunks = chunks[1:]
- }
- if len(chunks) == 0 {
- return nil
- }
- return chunks
-}
diff --git a/prometheus/testutil/diff/diff_test.go b/prometheus/testutil/diff/diff_test.go
deleted file mode 100644
index 6dfba99..0000000
--- a/prometheus/testutil/diff/diff_test.go
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2013 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// The code in this package is copy/paste to avoid a dependency. Hence this file
-// carries the copyright of the original repo.
-// https://github.com/kylelemons/godebug/tree/v1.1.0/diff
-package diff
-
-import (
- "fmt"
- "reflect"
- "strings"
- "testing"
-)
-
-func TestDiff(t *testing.T) {
- tests := []struct {
- desc string
- A, B []string
- chunks []Chunk
- }{
- {
- desc: "nil",
- },
- {
- desc: "empty",
- A: []string{},
- B: []string{},
- },
- {
- desc: "same",
- A: []string{"foo"},
- B: []string{"foo"},
- },
- {
- desc: "a empty",
- A: []string{},
- },
- {
- desc: "b empty",
- B: []string{},
- },
- {
- desc: "b nil",
- A: []string{"foo"},
- chunks: []Chunk{
- 0: {Deleted: []string{"foo"}},
- },
- },
- {
- desc: "a nil",
- B: []string{"foo"},
- chunks: []Chunk{
- 0: {Added: []string{"foo"}},
- },
- },
- {
- desc: "start with change",
- A: []string{"a", "b", "c"},
- B: []string{"A", "b", "c"},
- chunks: []Chunk{
- 0: {Deleted: []string{"a"}},
- 1: {Added: []string{"A"}, Equal: []string{"b", "c"}},
- },
- },
- {
- desc: "constitution",
- A: []string{
- "We the People of the United States, in Order to form a more perfect Union,",
- "establish Justice, insure domestic Tranquility, provide for the common defence,",
- "and secure the Blessings of Liberty to ourselves",
- "and our Posterity, do ordain and establish this Constitution for the United",
- "States of America.",
- },
- B: []string{
- "We the People of the United States, in Order to form a more perfect Union,",
- "establish Justice, insure domestic Tranquility, provide for the common defence,",
- "promote the general Welfare, and secure the Blessings of Liberty to ourselves",
- "and our Posterity, do ordain and establish this Constitution for the United",
- "States of America.",
- },
- chunks: []Chunk{
- 0: {
- Equal: []string{
- "We the People of the United States, in Order to form a more perfect Union,",
- "establish Justice, insure domestic Tranquility, provide for the common defence,",
- },
- },
- 1: {
- Deleted: []string{
- "and secure the Blessings of Liberty to ourselves",
- },
- },
- 2: {
- Added: []string{
- "promote the general Welfare, and secure the Blessings of Liberty to ourselves",
- },
- Equal: []string{
- "and our Posterity, do ordain and establish this Constitution for the United",
- "States of America.",
- },
- },
- },
- },
- }
-
- for _, test := range tests {
- t.Run(test.desc, func(t *testing.T) {
- got := DiffChunks(test.A, test.B)
- if got, want := len(got), len(test.chunks); got != want {
- t.Errorf("edit distance = %v, want %v", got-1, want-1)
- return
- }
- for i := range got {
- got, want := got[i], test.chunks[i]
- if got, want := got.Added, want.Added; !reflect.DeepEqual(got, want) {
- t.Errorf("chunks[%d]: Added = %v, want %v", i, got, want)
- }
- if got, want := got.Deleted, want.Deleted; !reflect.DeepEqual(got, want) {
- t.Errorf("chunks[%d]: Deleted = %v, want %v", i, got, want)
- }
- if got, want := got.Equal, want.Equal; !reflect.DeepEqual(got, want) {
- t.Errorf("chunks[%d]: Equal = %v, want %v", i, got, want)
- }
- }
- })
- }
-}
-
-func TestRender(t *testing.T) {
- tests := []struct {
- desc string
- chunks []Chunk
- out string
- }{
- {
- desc: "ordering",
- chunks: []Chunk{
- {
- Added: []string{"1"},
- Deleted: []string{"2"},
- Equal: []string{"3"},
- },
- {
- Added: []string{"4"},
- Deleted: []string{"5"},
- },
- },
- out: strings.TrimSpace(`
-+1
--2
- 3
-+4
--5
- `),
- },
- {
- desc: "only_added",
- chunks: []Chunk{
- {
- Added: []string{"1"},
- },
- },
- out: strings.TrimSpace(`
-+1
- `),
- },
- {
- desc: "only_deleted",
- chunks: []Chunk{
- {
- Deleted: []string{"1"},
- },
- },
- out: strings.TrimSpace(`
--1
- `),
- },
- }
-
- for _, test := range tests {
- t.Run(test.desc, func(t *testing.T) {
- if got, want := Render(test.chunks), test.out; got != want {
- t.Errorf("Render(%q):", test.chunks)
- t.Errorf("GOT\n%s", got)
- t.Errorf("WANT\n%s", want)
- }
- })
- }
-}
-
-func ExampleDiff() {
- constitution := strings.TrimSpace(`
-We the People of the United States, in Order to form a more perfect Union,
-establish Justice, insure domestic Tranquility, provide for the common defence,
-promote the general Welfare, and secure the Blessings of Liberty to ourselves
-and our Posterity, do ordain and establish this Constitution for the United
-States of America.
-`)
-
- got := strings.TrimSpace(`
-:wq
-We the People of the United States, in Order to form a more perfect Union,
-establish Justice, insure domestic Tranquility, provide for the common defence,
-and secure the Blessings of Liberty to ourselves
-and our Posterity, do ordain and establish this Constitution for the United
-States of America.
-`)
-
- fmt.Println(Diff(got, constitution))
-
- // Output:
- // -:wq
- // We the People of the United States, in Order to form a more perfect Union,
- // establish Justice, insure domestic Tranquility, provide for the common defence,
- // -and secure the Blessings of Liberty to ourselves
- // +promote the general Welfare, and secure the Blessings of Liberty to ourselves
- // and our Posterity, do ordain and establish this Constitution for the United
- // States of America.
-}
diff --git a/prometheus/testutil/testutil.go b/prometheus/testutil/testutil.go
index de7eaf1..92d0479 100644
--- a/prometheus/testutil/testutil.go
+++ b/prometheus/testutil/testutil.go
@@ -43,13 +43,13 @@
"io"
"net/http"
+ "github.com/google/go-cmp/cmp"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
"google.golang.org/protobuf/proto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/internal"
- "github.com/prometheus/client_golang/prometheus/testutil/diff"
)
// ToFloat64 collects all Metrics from the provided Collector. It expects that
@@ -309,7 +309,7 @@
return fmt.Errorf("encoding expected metrics failed: %w", err)
}
}
- if diffErr := diff.Diff(gotBuf.String(), wantBuf.String()); diffErr != "" {
+ if diffErr := cmp.Diff(gotBuf.String(), wantBuf.String()); diffErr != "" {
return fmt.Errorf(diffErr)
}
return nil
diff --git a/prometheus/testutil/testutil_test.go b/prometheus/testutil/testutil_test.go
index ec835a6..136bdf9 100644
--- a/prometheus/testutil/testutil_test.go
+++ b/prometheus/testutil/testutil_test.go
@@ -309,22 +309,10 @@
some_other_metric{label1="value1"} 1
`
- expectedError := `-# HELP some_total A value that represents a counter.
--# TYPE some_total counter
--some_total{label1="value1"} 1
-+# HELP some_other_metric A value that represents a counter.
-+# TYPE some_other_metric counter
-+some_other_metric{label1="value1"} 1
- `
-
err := CollectAndCompare(c, strings.NewReader(metadata+expected))
if err == nil {
t.Error("Expected error, got no error.")
}
-
- if err.Error() != expectedError {
- t.Errorf("Expected\n%#+v\nGot:\n%#+v", expectedError, err.Error())
- }
}
func TestScrapeAndCompare(t *testing.T) {