Move the load-test origin's logic into internal/loadtestorigin
REPO_POLICIES.md requires cmd/ to be thin: one main.go whose body is a single call into internal/ or pkg/. The image, the handler, the server and their test move unchanged into internal/loadtestorigin, whose Run does what main did; cmd/loadtest-origin/main.go only calls it. Model: opus-5-5
This commit is contained in:
@@ -1,84 +1,9 @@
|
|||||||
// Command loadtest-origin is the upstream host script/loadtest points pixad
|
// Command loadtest-origin is the upstream host script/loadtest points pixad
|
||||||
// at. It answers every request, whatever its path, with the same generated
|
// at; internal/loadtestorigin says what it does.
|
||||||
// JPEG, so each new path is a new source image for pixad to fetch, and it logs
|
|
||||||
// one line per request, so its log counts pixad's fetches.
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "sneak.berlin/go/pixa/internal/loadtestorigin"
|
||||||
"bytes"
|
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
"image/jpeg"
|
|
||||||
"log/slog"
|
|
||||||
"math"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
listenAddress = ":80"
|
|
||||||
readHeaderTimeout = 10 * time.Second
|
|
||||||
imageWidth = 1600
|
|
||||||
imageHeight = 1200
|
|
||||||
jpegQuality = 85
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
photo, err := makeJPEG()
|
loadtestorigin.Run()
|
||||||
if err != nil {
|
|
||||||
slog.Error("cannot make the image", "error", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
server := &http.Server{
|
|
||||||
Addr: listenAddress,
|
|
||||||
Handler: newHandler(photo),
|
|
||||||
ReadHeaderTimeout: readHeaderTimeout,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = server.ListenAndServe()
|
|
||||||
slog.Error("server stopped", "error", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newHandler answers every request with photo and logs the request's path.
|
|
||||||
func newHandler(photo []byte) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
slog.Info("request", "path", r.URL.Path)
|
|
||||||
w.Header().Set("Content-Type", "image/jpeg")
|
|
||||||
_, _ = w.Write(photo)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeJPEG draws colour gradients crossed with a fine pattern, so the image
|
|
||||||
// has detail to decode and does not compress to almost nothing.
|
|
||||||
func makeJPEG() ([]byte, error) {
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, imageWidth, imageHeight))
|
|
||||||
|
|
||||||
// red and green count up from 0 to 255 and wrap around, along each row
|
|
||||||
// and down the image.
|
|
||||||
var green uint8
|
|
||||||
|
|
||||||
for y := range imageHeight {
|
|
||||||
var red uint8
|
|
||||||
|
|
||||||
for x := range imageWidth {
|
|
||||||
img.SetRGBA(x, y, color.RGBA{
|
|
||||||
R: red, G: green, B: red ^ green, A: math.MaxUint8,
|
|
||||||
})
|
|
||||||
red++
|
|
||||||
}
|
|
||||||
|
|
||||||
green++
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: jpegQuality})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
// Package loadtestorigin is the upstream host script/loadtest points pixad
|
||||||
|
// at, run by cmd/loadtest-origin. It answers every request, whatever its path,
|
||||||
|
// with the same generated JPEG, so each new path is a new source image for
|
||||||
|
// pixad to fetch, and it logs one line per request, so its log counts pixad's
|
||||||
|
// fetches.
|
||||||
|
package loadtestorigin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/jpeg"
|
||||||
|
"log/slog"
|
||||||
|
"math"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
listenAddress = ":80"
|
||||||
|
readHeaderTimeout = 10 * time.Second
|
||||||
|
imageWidth = 1600
|
||||||
|
imageHeight = 1200
|
||||||
|
jpegQuality = 85
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run makes the image and serves it on port 80 until the server fails, then
|
||||||
|
// exits the process with status 1.
|
||||||
|
func Run() {
|
||||||
|
photo, err := makeJPEG()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("cannot make the image", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &http.Server{
|
||||||
|
Addr: listenAddress,
|
||||||
|
Handler: newHandler(photo),
|
||||||
|
ReadHeaderTimeout: readHeaderTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = server.ListenAndServe()
|
||||||
|
slog.Error("server stopped", "error", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newHandler answers every request with photo and logs the request's path.
|
||||||
|
func newHandler(photo []byte) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
slog.Info("request", "path", r.URL.Path)
|
||||||
|
w.Header().Set("Content-Type", "image/jpeg")
|
||||||
|
_, _ = w.Write(photo)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeJPEG draws colour gradients crossed with a fine pattern, so the image
|
||||||
|
// has detail to decode and does not compress to almost nothing.
|
||||||
|
func makeJPEG() ([]byte, error) {
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, imageWidth, imageHeight))
|
||||||
|
|
||||||
|
// red and green count up from 0 to 255 and wrap around, along each row
|
||||||
|
// and down the image.
|
||||||
|
var green uint8
|
||||||
|
|
||||||
|
for y := range imageHeight {
|
||||||
|
var red uint8
|
||||||
|
|
||||||
|
for x := range imageWidth {
|
||||||
|
img.SetRGBA(x, y, color.RGBA{
|
||||||
|
R: red, G: green, B: red ^ green, A: math.MaxUint8,
|
||||||
|
})
|
||||||
|
red++
|
||||||
|
}
|
||||||
|
|
||||||
|
green++
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: jpegQuality})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package loadtestorigin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
Reference in New Issue
Block a user