mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 09:01:31 +00:00
c8d42ac160
S3 was the one served surface with no coverage page. The gateway has no operation-name dispatch table for it, so there was nothing to compare against the model. Predastore now declares the operations each of its S3 routes answers, so the generator compares that inventory the same way it compares the other nine services. The page credits Predastore rather than Spinifex, and its intro separates what is routed from what conforms, pointing at the ceph/s3-tests report for the second.
167 lines
4.6 KiB
Go
167 lines
4.6 KiB
Go
package awsmodel_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
. "github.com/mulgadc/spinifex/internal/awsmodel"
|
|
)
|
|
|
|
// stagePages copies the checked-in metadata into a temp directory so a write
|
|
// test cannot touch docs/coverage.
|
|
func stagePages(t *testing.T) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
contents, err := os.ReadFile(filepath.Join("..", "..", "docs", "coverage", "pages.json"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, "pages.json"), contents, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return dir
|
|
}
|
|
|
|
func stsCoverage(t *testing.T) OperationCoverage {
|
|
t.Helper()
|
|
coverage, err := CompareOperations(STS, DispatchInventory{Registered: []string{"AssumeRole"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return coverage
|
|
}
|
|
|
|
func TestWritePagesWritesAServicePageAndTheIndex(t *testing.T) {
|
|
dir := stagePages(t)
|
|
|
|
if err := WritePages(dir, []OperationCoverage{stsCoverage(t)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
service, err := os.ReadFile(filepath.Join(dir, "sts", "README.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(service), "| `AssumeRole` |") {
|
|
t.Errorf("service page is missing its operation table:\n%s", service)
|
|
}
|
|
index, err := os.ReadFile(filepath.Join(dir, "README.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(index), "[STS](/coverage/sts)") {
|
|
t.Errorf("index does not link the service page:\n%s", index)
|
|
}
|
|
}
|
|
|
|
// The gaps the pages leave out are still written down, in a file the docs site
|
|
// is not configured to render.
|
|
func TestWritePagesWritesTheInternalReport(t *testing.T) {
|
|
dir := stagePages(t)
|
|
coverage := stsCoverage(t)
|
|
|
|
if err := WritePages(dir, []OperationCoverage{coverage}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
report, err := os.ReadFile(filepath.Join(dir, "internal-report.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, operation := range coverage.Missing {
|
|
if !strings.Contains(string(report), "- `"+operation+"`") {
|
|
t.Errorf("internal report omits unimplemented operation %q:\n%s", operation, report)
|
|
}
|
|
}
|
|
if !strings.Contains(string(report), "% ") && !strings.Contains(string(report), "%)") {
|
|
t.Errorf("internal report carries no coverage figure:\n%s", report)
|
|
}
|
|
}
|
|
|
|
func TestWritePagesIncludesAnIntroAndOverwritesTheGeneratedPage(t *testing.T) {
|
|
dir := stagePages(t)
|
|
pageDir := filepath.Join(dir, "sts")
|
|
if err := os.MkdirAll(pageDir, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(pageDir, "intro.md"), []byte("### Scope\n\nCarried prose.\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(pageDir, "README.md"), []byte("stale hand edit"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := WritePages(dir, []OperationCoverage{stsCoverage(t)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
page, err := os.ReadFile(filepath.Join(pageDir, "README.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(string(page), "stale hand edit") {
|
|
t.Error("a hand edit to a generated page survived regeneration")
|
|
}
|
|
if !strings.Contains(string(page), "### Scope\n\nCarried prose.") {
|
|
t.Errorf("page does not carry its intro:\n%s", page)
|
|
}
|
|
}
|
|
|
|
// A service the page set does not describe is skipped rather than crashing the
|
|
// run or publishing a page with no metadata on it.
|
|
func TestWritePagesSkipsAServiceWithNoMetadata(t *testing.T) {
|
|
dir := stageWithout(t, S3)
|
|
coverage, err := CompareOperations(S3, DispatchInventory{Registered: []string{"ListBuckets"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := WritePages(dir, []OperationCoverage{coverage}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(dir, "s3")); !os.IsNotExist(err) {
|
|
t.Errorf("a page was written for a service with no metadata: %v", err)
|
|
}
|
|
}
|
|
|
|
// stageWithout stages the checked-in metadata with one service dropped, for the
|
|
// cases about a service the page set does not describe.
|
|
func stageWithout(t *testing.T, service Service) string {
|
|
t.Helper()
|
|
dir := stagePages(t)
|
|
path := filepath.Join(dir, "pages.json")
|
|
contents, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var pages map[string]any
|
|
if err := json.Unmarshal(contents, &pages); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
services, ok := pages["services"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("staged metadata has no services: %s", contents)
|
|
}
|
|
delete(services, string(service))
|
|
|
|
reduced, err := json.Marshal(pages)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, reduced, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return dir
|
|
}
|
|
|
|
func TestWritePagesReportsMissingMetadata(t *testing.T) {
|
|
if err := WritePages(t.TempDir(), nil); err == nil {
|
|
t.Fatal("WritePages accepted a directory with no pages.json")
|
|
}
|
|
}
|