The entry said to measure first and put the number in the commit, so: a plain page renders in 14µs, a twelve-picture gallery in 1.23ms. Of that, ~102µs per picture was reading, hashing and decoding bytes the previous request had already read. Remembering that one fact — keyed by path, size and modification time — brings the same gallery to 63µs. 19.5× faster, 21× fewer bytes allocated, twenty-odd lines. After which nothing is slow enough to justify caching whole pages, so ADR-0044 declines the page cache and leaves the parked validity model parked, now with a measurement rather than an intuition behind its trigger. That parked model has five axes and was written before any code existed. The problem it would have been built for turned out to be one repeated file read. Benchmarks live in internal/web so they measure through the real handler, which is also what conventions.md wants before any cache goes in the render path. The invalidation risk has its own test: an edited picture is a different key, so the memo cannot serve yesterday's dimensions. Everything runs clean under -race, since the map is read by concurrent requests.
153 lines
4.7 KiB
Go
153 lines
4.7 KiB
Go
package shortcodes
|
|
|
|
import (
|
|
"bytes"
|
|
"image"
|
|
"image/color"
|
|
"image/jpeg"
|
|
"image/png"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
"testing/fstest"
|
|
"time"
|
|
|
|
"khosra/internal/render"
|
|
)
|
|
|
|
// wide builds a real encoded picture of a given width, so the tests exercise decoding rather than a stub.
|
|
func wide(t *testing.T, width int, asPNG bool) []byte {
|
|
t.Helper()
|
|
img := image.NewRGBA(image.Rect(0, 0, width, width/2))
|
|
for x := range width {
|
|
for y := range width / 2 {
|
|
img.Set(x, y, color.RGBA{uint8(x % 256), uint8(y % 256), 128, 255})
|
|
}
|
|
}
|
|
var out bytes.Buffer
|
|
var err error
|
|
if asPNG {
|
|
err = png.Encode(&out, img)
|
|
} else {
|
|
err = jpeg.Encode(&out, img, nil)
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return out.Bytes()
|
|
}
|
|
|
|
func TestDeriveMakesEachMissingWidthAndIsIdempotent(t *testing.T) {
|
|
cache := t.TempDir()
|
|
big := wide(t, 2000, false)
|
|
fsys := fstest.MapFS{
|
|
"content/art/set/index.md": {Data: []byte("---\ntitle: Set\n---\n")},
|
|
"content/art/set/big.jpg": {Data: big},
|
|
"content/art/set/small.png": {Data: wide(t, 300, true)}, // narrower than every target
|
|
"content/art/set/notes.md": {Data: []byte("not a picture")},
|
|
}
|
|
made, err := Derive(fsys, cache)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if made != len(widths) {
|
|
t.Errorf("made %d derivatives, want %d — one per width below the original's", made, len(widths))
|
|
}
|
|
// Never upscale: nothing is made for a picture already narrower than the targets.
|
|
entries, err := os.ReadDir(cache)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(entries) != len(widths) {
|
|
t.Errorf("cache holds %d files, want %d", len(entries), len(widths))
|
|
}
|
|
// Each is a real image of the width it claims.
|
|
for _, e := range entries {
|
|
data, err := os.ReadFile(filepath.Join(cache, e.Name()))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, _, err := image.DecodeConfig(bytes.NewReader(data))
|
|
if err != nil {
|
|
t.Fatalf("%s is not a decodable image: %v", e.Name(), err)
|
|
}
|
|
if !strings.Contains(e.Name(), "-w"+strconv.Itoa(cfg.Width)) {
|
|
t.Errorf("%s decodes to width %d, which its name does not claim", e.Name(), cfg.Width)
|
|
}
|
|
if cfg.Height != cfg.Width/2 {
|
|
t.Errorf("%s is %dx%d — the aspect ratio was not kept", e.Name(), cfg.Width, cfg.Height)
|
|
}
|
|
}
|
|
// A second pass writes nothing: the name is the source's content, so there is nothing new to make.
|
|
again, err := Derive(fsys, cache)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if again != 0 {
|
|
t.Errorf("second pass made %d, want 0 — the pass must be idempotent (ADR-0042)", again)
|
|
}
|
|
}
|
|
|
|
func TestAnEditedPictureGetsADifferentName(t *testing.T) {
|
|
// Content-addressed, so a stale derivative can never be served under a name that now means something else.
|
|
first := derivedName(wide(t, 1000, false), "content/a/x.jpg", 480)
|
|
second := derivedName(wide(t, 1200, false), "content/a/x.jpg", 480)
|
|
if first == second {
|
|
t.Error("two different pictures must not share a derivative name")
|
|
}
|
|
if derivedName([]byte("same"), "a.png", 480) == derivedName([]byte("same"), "a.png", 960) {
|
|
t.Error("two widths of one picture must not share a name either")
|
|
}
|
|
if !strings.HasSuffix(derivedName([]byte("x"), "a.png", 480), ".png") {
|
|
t.Error("a source that may carry transparency keeps a lossless derivative")
|
|
}
|
|
}
|
|
|
|
func TestOriginalsAreNeverTouched(t *testing.T) {
|
|
cache := t.TempDir()
|
|
big := wide(t, 2000, false)
|
|
original := append([]byte(nil), big...)
|
|
fsys := fstest.MapFS{"content/art/set/big.jpg": {Data: big}}
|
|
if _, err := Derive(fsys, cache); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
after, err := fsys.ReadFile("content/art/set/big.jpg")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(original, after) {
|
|
t.Error("the author's own file was modified")
|
|
}
|
|
}
|
|
|
|
func TestAnEditedPictureIsInspectedAgain(t *testing.T) {
|
|
// The whole risk of remembering: serving yesterday's size or srcset. The key carries size and modification
|
|
// time, so an edit is a different key rather than a stale hit.
|
|
fsys := fstest.MapFS{
|
|
"content/art/set/index.md": {Data: []byte("---\ntitle: Set\n---\n")},
|
|
"content/art/set/one.jpg": {Data: wide(t, 1200, false), ModTime: time.Unix(1000, 0)},
|
|
}
|
|
origin := render.Origin{Dir: "content/art/set", Files: fsys}
|
|
first, ok := picture(origin, "one.jpg")
|
|
if !ok || first.Width != 1200 {
|
|
t.Fatalf("first inspection = %+v", first)
|
|
}
|
|
if again, _ := picture(origin, "one.jpg"); again != first {
|
|
t.Errorf("a second look at the same file should be identical, got %+v", again)
|
|
}
|
|
|
|
fsys["content/art/set/one.jpg"] = &fstest.MapFile{Data: wide(t, 800, false), ModTime: time.Unix(2000, 0)}
|
|
edited, ok := picture(origin, "one.jpg")
|
|
if !ok {
|
|
t.Fatal("still a picture")
|
|
}
|
|
if edited.Width != 800 {
|
|
t.Errorf("width = %d, want 800 — the edit was not noticed", edited.Width)
|
|
}
|
|
if edited.Srcset == first.Srcset {
|
|
t.Error("the srcset should name different derivatives after an edit")
|
|
}
|
|
}
|