Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Fok <foka@debian.org>2019-10-07 21:35:00 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-10-07 22:52:43 +0300
commit39ed33fcebcde91605e645fd28fd94020b442d97 (patch)
tree67af004797c57614dffe99db462844356d78ac80 /resources
parent020a6fbd7f6996ed84d80ba6c37fe0d8c2536806 (diff)
resources: Fix image test error on s390x, ppc64* and arm64
In TestImageOperationsGolden, tolerate slight floating-point rounding differences due to the use or non-use of "fused multiply and add" (FMA) instruction on different architectures. Special thanks to @disintegration for the solution in goldenEqual(); see https://github.com/disintegration/gift/issues/20 Fixes #6387
Diffstat (limited to 'resources')
-rw-r--r--resources/image_test.go83
1 files changed, 78 insertions, 5 deletions
diff --git a/resources/image_test.go b/resources/image_test.go
index 169f19522..4b88b7aa1 100644
--- a/resources/image_test.go
+++ b/resources/image_test.go
@@ -15,6 +15,7 @@ package resources
import (
"fmt"
+ "image"
"io/ioutil"
"math/big"
"math/rand"
@@ -22,6 +23,7 @@ import (
"path"
"path/filepath"
"regexp"
+ "runtime"
"strconv"
"sync"
"testing"
@@ -478,6 +480,47 @@ func BenchmarkImageExif(b *testing.B) {
}
+// usesFMA indicates whether "fused multiply and add" (FMA) instruction is
+// used. The command "grep FMADD go/test/codegen/floats.go" can help keep
+// the FMA-using architecture list updated.
+var usesFMA = runtime.GOARCH == "s390x" ||
+ runtime.GOARCH == "ppc64" ||
+ runtime.GOARCH == "ppc64le" ||
+ runtime.GOARCH == "arm64"
+
+// goldenEqual compares two NRGBA images. It is used in golden tests only.
+// A small tolerance is allowed on architectures using "fused multiply and add"
+// (FMA) instruction to accommodate for floating-point rounding differences
+// with control golden images that were generated on amd64 architecture.
+// See https://golang.org/ref/spec#Floating_point_operators
+// and https://github.com/gohugoio/hugo/issues/6387 for more information.
+//
+// Borrowed from https://github.com/disintegration/gift/blob/a999ff8d5226e5ab14b64a94fca07c4ac3f357cf/gift_test.go#L598-L625
+// Copyright (c) 2014-2019 Grigory Dryapak
+// Licensed under the MIT License.
+func goldenEqual(img1, img2 *image.NRGBA) bool {
+ maxDiff := 0
+ if usesFMA {
+ maxDiff = 1
+ }
+ if !img1.Rect.Eq(img2.Rect) {
+ return false
+ }
+ if len(img1.Pix) != len(img2.Pix) {
+ return false
+ }
+ for i := 0; i < len(img1.Pix); i++ {
+ diff := int(img1.Pix[i]) - int(img2.Pix[i])
+ if diff < 0 {
+ diff = -diff
+ }
+ if diff > maxDiff {
+ return false
+ }
+ }
+ return true
+}
+
func TestImageOperationsGolden(t *testing.T) {
c := qt.New(t)
c.Parallel()
@@ -580,21 +623,51 @@ func TestImageOperationsGolden(t *testing.T) {
}
fi2 := dirinfos2[i]
c.Assert(fi1.Name(), qt.Equals, fi2.Name())
- c.Assert(fi1, eq, fi2)
+
f1, err := os.Open(filepath.Join(dir1, fi1.Name()))
c.Assert(err, qt.IsNil)
f2, err := os.Open(filepath.Join(dir2, fi2.Name()))
c.Assert(err, qt.IsNil)
- hash1, err := helpers.MD5FromReader(f1)
+ img1, _, err := image.Decode(f1)
c.Assert(err, qt.IsNil)
- hash2, err := helpers.MD5FromReader(f2)
+ img2, _, err := image.Decode(f2)
c.Assert(err, qt.IsNil)
+ nrgba1 := image.NewNRGBA(img1.Bounds())
+ gift.New().Draw(nrgba1, img1)
+ nrgba2 := image.NewNRGBA(img2.Bounds())
+ gift.New().Draw(nrgba2, img2)
+
+ if !goldenEqual(nrgba1, nrgba2) {
+ switch fi1.Name() {
+ case "gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_4c320010919da2d8b63ed24818b4d8e1.png",
+ "gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_9d4c2220235b3c2d9fa6506be571560f.png",
+ "gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_c74bb417b961e09cf1aac2130b7b9b85.png":
+ c.Log("expectedly differs from golden due to dithering:", fi1.Name())
+ default:
+ t.Errorf("resulting image differs from golden: %s", fi1.Name())
+ }
+ }
+
+ if !usesFMA {
+ c.Assert(fi1, eq, fi2)
+
+ _, err = f1.Seek(0, 0)
+ c.Assert(err, qt.IsNil)
+ _, err = f2.Seek(0, 0)
+ c.Assert(err, qt.IsNil)
+
+ hash1, err := helpers.MD5FromReader(f1)
+ c.Assert(err, qt.IsNil)
+ hash2, err := helpers.MD5FromReader(f2)
+ c.Assert(err, qt.IsNil)
+
+ c.Assert(hash1, qt.Equals, hash2)
+ }
+
f1.Close()
f2.Close()
-
- c.Assert(hash1, qt.Equals, hash2)
}
}