mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
chore: update compatibility pages
This commit is contained in:
@@ -84,7 +84,10 @@ func writePages(outputDir string, coverages []awsmodel.OperationCoverage) error
|
||||
}
|
||||
|
||||
for _, coverage := range coverages {
|
||||
page := pages.Services[coverage.Service]
|
||||
page, ok := pages.Services[coverage.Service]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
intro, err := readIntro(outputDir, page.Slug)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -30,14 +30,6 @@ Terraform's canonical certificate, DNS record and validation flow works unmodifi
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AddTagsToCertificate` | ✅ Implemented |
|
||||
|
||||
@@ -29,17 +29,4 @@ Spinifex serves the AWS APIs below. Every page counts the operations in the pinn
|
||||
| [ELBv2](/docs/elbv2-api-coverage) | 2015-12-01 | 33 | 46 | 71.7% |
|
||||
| [IAM](/docs/iam-api-coverage) | 2010-05-08 | 75 | 159 | 47.2% |
|
||||
| [RDS](/docs/rds-api-coverage) | 2014-10-31 | 26 | 162 | 16.0% |
|
||||
| [S3](/docs/s3-api-coverage) | 2006-03-01 | — | 99 | — |
|
||||
| [STS](/docs/sts-api-coverage) | 2011-06-15 | 4 | 8 | 50.0% |
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
### What "implemented" means here
|
||||
|
||||
An operation is implemented when the gateway binds it to a real handler. These pages are generated from those dispatch tables on every build, so they cannot go stale against the code. That is a mechanical fact, and it is the only claim they make. It does not say the handler honours every parameter AWS models, and no page reports parameter or field-level detail: a handler receives a fully-populated typed SDK struct, so nothing distinguishes a field it honours from one it ignores. Behavioural conformance is measured separately by the integration conformance suite.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
### What "implemented" means here
|
||||
|
||||
An operation is implemented when the gateway binds it to a real handler. These pages are generated from those dispatch tables on every build, so they cannot go stale against the code. That is a mechanical fact, and it is the only claim they make. It does not say the handler honours every parameter AWS models, and no page reports parameter or field-level detail: a handler receives a fully-populated typed SDK struct, so nothing distinguishes a field it honours from one it ignores. Behavioural conformance is measured separately by the integration conformance suite.
|
||||
@@ -28,14 +28,6 @@ Spot Instance Requests are a mock over the on-demand `RunInstances` path. A requ
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AcceptAddressTransfer` | ❌ Not implemented |
|
||||
|
||||
@@ -30,14 +30,6 @@ Vulnerability scanning is not offered, so the image-scanning operations refuse d
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `BatchCheckLayerAvailability` | 🟡 Stub |
|
||||
|
||||
@@ -26,14 +26,6 @@ Clusters, services and tasks run on EC2 container instances. There is no Fargate
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `CreateCapacityProvider` | ✅ Implemented |
|
||||
|
||||
@@ -37,14 +37,6 @@ None is callable with an ordinary tenant credential. Each names the target accou
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AssociateAccessPolicy` | ✅ Implemented |
|
||||
|
||||
@@ -26,14 +26,6 @@ The data plane is a system-managed load balancer VM, launched automatically duri
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AddListenerCertificates` | ✅ Implemented |
|
||||
|
||||
@@ -26,14 +26,6 @@ All IAM operations are account-scoped. The root user of an account bypasses poli
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AddClientIDToOpenIDConnectProvider` | ❌ Not implemented |
|
||||
|
||||
@@ -6,7 +6,13 @@
|
||||
"title": "AWS API Coverage",
|
||||
"seoTitle": "Which AWS API Operations Spinifex Implements — Spinifex Docs",
|
||||
"description": "Operation-level coverage of every AWS API Spinifex serves, generated from its gateway dispatch tables and the pinned AWS SDK service models on each build.",
|
||||
"tags": ["aws", "compatibility", "coverage", "api", "operations"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"api",
|
||||
"operations"
|
||||
]
|
||||
},
|
||||
"services": {
|
||||
"acm": {
|
||||
@@ -15,7 +21,14 @@
|
||||
"title": "ACM API Coverage",
|
||||
"seoTitle": "AWS Certificate Manager API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the AWS Certificate Manager API model and whether Spinifex implements it, generated from the gateway dispatch tables on each build.",
|
||||
"tags": ["aws", "compatibility", "coverage", "acm", "certificates", "tls"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"acm",
|
||||
"certificates",
|
||||
"tls"
|
||||
]
|
||||
},
|
||||
"ec2": {
|
||||
"slug": "ec2-api-coverage",
|
||||
@@ -23,7 +36,14 @@
|
||||
"title": "EC2 API Coverage",
|
||||
"seoTitle": "Amazon EC2 API Coverage on Spinifex — Spinifex Docs",
|
||||
"description": "Every operation in the Amazon EC2 API model and whether Spinifex implements it, covering instances, EBS volumes, VPC networking, tags and security groups.",
|
||||
"tags": ["aws", "compatibility", "coverage", "ec2", "compute", "vpc"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"ec2",
|
||||
"compute",
|
||||
"vpc"
|
||||
]
|
||||
},
|
||||
"ecr": {
|
||||
"slug": "ecr-api-coverage",
|
||||
@@ -31,7 +51,14 @@
|
||||
"title": "ECR API Coverage",
|
||||
"seoTitle": "Elastic Container Registry API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the Amazon ECR API model and whether Spinifex implements it, alongside the OCI distribution endpoint that carries the image layers.",
|
||||
"tags": ["aws", "compatibility", "coverage", "ecr", "containers", "registry"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"ecr",
|
||||
"containers",
|
||||
"registry"
|
||||
]
|
||||
},
|
||||
"ecs": {
|
||||
"slug": "ecs-api-coverage",
|
||||
@@ -39,7 +66,14 @@
|
||||
"title": "ECS API Coverage",
|
||||
"seoTitle": "Elastic Container Service API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the Amazon ECS API model and whether Spinifex implements it, covering clusters, services, tasks and container instances on each build.",
|
||||
"tags": ["aws", "compatibility", "coverage", "ecs", "containers", "orchestration"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"ecs",
|
||||
"containers",
|
||||
"orchestration"
|
||||
]
|
||||
},
|
||||
"eks": {
|
||||
"slug": "eks-api-coverage",
|
||||
@@ -47,7 +81,14 @@
|
||||
"title": "EKS API Coverage",
|
||||
"seoTitle": "Elastic Kubernetes Service API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the Amazon EKS API model and whether Spinifex implements it, covering clusters, nodegroups, add-ons and access entries on each build.",
|
||||
"tags": ["aws", "compatibility", "coverage", "eks", "kubernetes", "containers"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"eks",
|
||||
"kubernetes",
|
||||
"containers"
|
||||
]
|
||||
},
|
||||
"elasticloadbalancingv2": {
|
||||
"slug": "elbv2-api-coverage",
|
||||
@@ -55,7 +96,14 @@
|
||||
"title": "ELBv2 API Coverage",
|
||||
"seoTitle": "Elastic Load Balancing v2 API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the Elastic Load Balancing v2 API model and whether Spinifex implements it, for both the Application and Network Load Balancers it serves.",
|
||||
"tags": ["aws", "compatibility", "coverage", "elbv2", "load balancing", "networking"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"elbv2",
|
||||
"load balancing",
|
||||
"networking"
|
||||
]
|
||||
},
|
||||
"iam": {
|
||||
"slug": "iam-api-coverage",
|
||||
@@ -63,7 +111,14 @@
|
||||
"title": "IAM API Coverage",
|
||||
"seoTitle": "AWS IAM API Operation Coverage on Spinifex — Spinifex Docs",
|
||||
"description": "Every operation in the AWS IAM API model and whether Spinifex implements it, covering users, roles, policies, groups and instance profiles on each build.",
|
||||
"tags": ["aws", "compatibility", "coverage", "iam", "identity", "policies"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"iam",
|
||||
"identity",
|
||||
"policies"
|
||||
]
|
||||
},
|
||||
"rds": {
|
||||
"slug": "rds-api-coverage",
|
||||
@@ -71,15 +126,15 @@
|
||||
"title": "RDS API Coverage",
|
||||
"seoTitle": "Relational Database Service API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the Amazon RDS API model and whether Spinifex implements it, for the managed PostgreSQL and MariaDB engines it offers on each build.",
|
||||
"tags": ["aws", "compatibility", "coverage", "rds", "databases", "postgresql", "mariadb"]
|
||||
},
|
||||
"s3": {
|
||||
"slug": "s3-api-coverage",
|
||||
"name": "S3",
|
||||
"title": "S3 API Coverage",
|
||||
"seoTitle": "Amazon S3 API Compatibility on Spinifex — Spinifex Docs",
|
||||
"description": "How Spinifex serves the Amazon S3 API through Predastore, and why its coverage is measured there rather than derived from a gateway dispatch table here.",
|
||||
"tags": ["aws", "compatibility", "coverage", "s3", "storage", "predastore"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"rds",
|
||||
"databases",
|
||||
"postgresql",
|
||||
"mariadb"
|
||||
]
|
||||
},
|
||||
"sts": {
|
||||
"slug": "sts-api-coverage",
|
||||
@@ -87,7 +142,14 @@
|
||||
"title": "STS API Coverage",
|
||||
"seoTitle": "AWS Security Token Service API Coverage — Spinifex Docs",
|
||||
"description": "Every operation in the AWS STS API model and whether Spinifex implements it, covering role assumption, session tokens and web identity federation (IRSA).",
|
||||
"tags": ["aws", "compatibility", "coverage", "sts", "identity", "credentials"]
|
||||
"tags": [
|
||||
"aws",
|
||||
"compatibility",
|
||||
"coverage",
|
||||
"sts",
|
||||
"identity",
|
||||
"credentials"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,14 +45,6 @@ A parameter whose omission would create a false safety, security or availability
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AddRoleToDBCluster` | ❌ Not implemented |
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
title: "S3 API Coverage"
|
||||
seoTitle: "Amazon S3 API Compatibility on Spinifex — Spinifex Docs"
|
||||
description: "How Spinifex serves the Amazon S3 API through Predastore, and why its coverage is measured there rather than derived from a gateway dispatch table here."
|
||||
category: "Coverage"
|
||||
sections:
|
||||
- overview
|
||||
tags:
|
||||
- aws
|
||||
- compatibility
|
||||
- coverage
|
||||
- s3
|
||||
- storage
|
||||
- predastore
|
||||
---
|
||||
|
||||
# S3 API Coverage
|
||||
|
||||
## Overview
|
||||
|
||||
The S3 API model pins **99** operations at API version `2006-03-01`, but Spinifex's coverage of them is not mechanically enumerable: Spinifex delegates the S3 REST surface to Predastore, which has no operation-name dispatch table to compare mechanically.
|
||||
|
||||
### Where S3 is served
|
||||
|
||||
Spinifex does not dispatch S3 operations. The REST surface is delegated whole to **Predastore**, which serves it directly, so there is no operation-name dispatch table in the gateway to compare against the model — the comparison that produces every other page on this site has nothing to read here.
|
||||
|
||||
That is why this page reports no percentage. Claiming one from an empty dispatch table would read as 0% implemented, which is the opposite of the truth: S3 is one of the most complete surfaces in the platform.
|
||||
|
||||
Predastore publishes its own measured compatibility. Consult it for the operations, headers and behaviours it supports.
|
||||
@@ -1,7 +0,0 @@
|
||||
### Where S3 is served
|
||||
|
||||
Spinifex does not dispatch S3 operations. The REST surface is delegated whole to **Predastore**, which serves it directly, so there is no operation-name dispatch table in the gateway to compare against the model — the comparison that produces every other page on this site has nothing to read here.
|
||||
|
||||
That is why this page reports no percentage. Claiming one from an empty dispatch table would read as 0% implemented, which is the opposite of the truth: S3 is one of the most complete surfaces in the platform.
|
||||
|
||||
Predastore publishes its own measured compatibility. Consult it for the operations, headers and behaviours it supports.
|
||||
@@ -32,14 +32,6 @@ Several inputs the model describes are deliberately rejected rather than accepte
|
||||
|
||||
### Operations
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| ✅ Implemented | A modelled operation bound to a real handler. |
|
||||
| 🟡 Stub | A registered handler that answers with a fixed or empty result. |
|
||||
| 🚫 Not supported | A registered handler that deliberately refuses, so a client sees "not offered" rather than an unknown action. |
|
||||
| ❌ Not implemented | Modelled by AWS, not registered by Spinifex. |
|
||||
| 🔒 Outside the pinned model | Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action. |
|
||||
|
||||
| Operation | Status |
|
||||
|---|---|
|
||||
| `AssumeRole` | ✅ Implemented |
|
||||
|
||||
+11
-38
@@ -108,10 +108,12 @@ func ParsePageSet(contents []byte) (PageSet, error) {
|
||||
if err := validatePage("index", pages.Index, slugs); err != nil {
|
||||
return PageSet{}, err
|
||||
}
|
||||
// A known service may be left out. S3 is: Predastore serves that surface,
|
||||
// so the gateway dispatch tables hold no honest number to publish for it.
|
||||
for _, service := range Services() {
|
||||
page, ok := pages.Services[service]
|
||||
if !ok {
|
||||
return PageSet{}, fmt.Errorf("awsmodel: coverage pages: no entry for service %q", service)
|
||||
continue
|
||||
}
|
||||
if err := validatePage(string(service), page, slugs); err != nil {
|
||||
return PageSet{}, err
|
||||
@@ -165,23 +167,24 @@ func RenderServicePage(coverage OperationCoverage, pages PageSet, intro string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("awsmodel: coverage pages: no entry for service %q", coverage.Service)
|
||||
}
|
||||
// An opaque service has no dispatch table to count, so there is no honest
|
||||
// number to put on a page. It is left out until a real one exists.
|
||||
if coverage.Opaque {
|
||||
return "", fmt.Errorf("awsmodel: %s coverage is not enumerable, so it has no publishable page", coverage.Service)
|
||||
}
|
||||
|
||||
var body strings.Builder
|
||||
writeFrontmatter(&body, page, pages.Category)
|
||||
fmt.Fprintf(&body, "# %s\n\n## Overview\n\n", page.Title)
|
||||
|
||||
writeSummary(&body, coverage, page)
|
||||
fmt.Fprintf(&body, "Spinifex implements **%d of the %d** operations in the %s `%s` API model, as pinned in `aws-sdk-go %s` — **%.1f%%**.\n\n",
|
||||
len(coverage.Implemented), len(coverage.Modelled), page.Name, coverage.APIVersion, SourceSDKVersion, coverage.ImplementedPercent())
|
||||
|
||||
if intro != "" {
|
||||
body.WriteString(strings.TrimSpace(intro) + "\n\n")
|
||||
}
|
||||
if coverage.Opaque {
|
||||
return strings.TrimRight(body.String(), "\n") + "\n", nil
|
||||
}
|
||||
|
||||
body.WriteString("### Operations\n\n")
|
||||
writeStatusLegend(&body)
|
||||
body.WriteString("\n| Operation | Status |\n|---|---|\n")
|
||||
body.WriteString("### Operations\n\n| Operation | Status |\n|---|---|\n")
|
||||
for _, status := range coverage.OperationStatuses() {
|
||||
fmt.Fprintf(&body, "| `%s` | %s |\n", status.Operation, status.Status)
|
||||
}
|
||||
@@ -202,48 +205,18 @@ func RenderIndexPage(coverages []OperationCoverage, pages PageSet, intro string)
|
||||
for _, coverage := range sortedCoverages(coverages) {
|
||||
page, ok := pages.Services[coverage.Service]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("awsmodel: coverage pages: no entry for service %q", coverage.Service)
|
||||
}
|
||||
if coverage.Opaque {
|
||||
fmt.Fprintf(&body, "| [%s](/docs/%s) | %s | — | %d | — |\n", page.Name, page.Slug, coverage.APIVersion, len(coverage.Modelled))
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(&body, "| [%s](/docs/%s) | %s | %d | %d | %.1f%% |\n",
|
||||
page.Name, page.Slug, coverage.APIVersion, len(coverage.Implemented), len(coverage.Modelled), coverage.ImplementedPercent())
|
||||
}
|
||||
|
||||
body.WriteString("\n")
|
||||
writeStatusLegend(&body)
|
||||
if intro != "" {
|
||||
body.WriteString("\n" + strings.TrimSpace(intro) + "\n")
|
||||
}
|
||||
return body.String(), nil
|
||||
}
|
||||
|
||||
// writeSummary states the implemented-of-modelled count, or why there is none.
|
||||
func writeSummary(body *strings.Builder, coverage OperationCoverage, page PageMetadata) {
|
||||
if coverage.Opaque {
|
||||
fmt.Fprintf(body, "The %s API model pins **%d** operations at API version `%s`, but Spinifex's coverage of them is not mechanically enumerable: %s\n\n",
|
||||
page.Name, len(coverage.Modelled), coverage.APIVersion, coverage.Note)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(body, "Spinifex implements **%d of the %d** operations in the %s `%s` API model, as pinned in `aws-sdk-go %s` — **%.1f%%**.\n\n",
|
||||
len(coverage.Implemented), len(coverage.Modelled), page.Name, coverage.APIVersion, SourceSDKVersion, coverage.ImplementedPercent())
|
||||
}
|
||||
|
||||
func writeStatusLegend(body *strings.Builder) {
|
||||
body.WriteString("| Status | Meaning |\n|---|---|\n")
|
||||
for _, entry := range [][2]string{
|
||||
{StatusImplemented, "A modelled operation bound to a real handler."},
|
||||
{StatusStub, "A registered handler that answers with a fixed or empty result."},
|
||||
{StatusNotSupported, "A registered handler that deliberately refuses, so a client sees \"not offered\" rather than an unknown action."},
|
||||
{StatusNotImplemented, "Modelled by AWS, not registered by Spinifex."},
|
||||
{StatusOutsideModel, "Registered by Spinifex but absent from the pinned model — an internal route, not a tenant-callable AWS action."},
|
||||
} {
|
||||
fmt.Fprintf(body, "| %s | %s |\n", entry[0], entry[1])
|
||||
}
|
||||
}
|
||||
|
||||
func writeFrontmatter(body *strings.Builder, page PageMetadata, category string) {
|
||||
body.WriteString("---\n")
|
||||
fmt.Fprintf(body, "title: %s\n", strconv.Quote(page.Title))
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package awsmodel
|
||||
package awsmodel_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/mulgadc/spinifex/internal/awsmodel"
|
||||
)
|
||||
|
||||
func testPageSet(t *testing.T) PageSet {
|
||||
@@ -23,10 +25,13 @@ func testPageSet(t *testing.T) PageSet {
|
||||
func TestParsePageSetAcceptsTheCheckedInFile(t *testing.T) {
|
||||
pages := testPageSet(t)
|
||||
|
||||
for _, service := range Services() {
|
||||
if _, ok := pages.Services[service]; !ok {
|
||||
t.Errorf("no page metadata for service %q", service)
|
||||
}
|
||||
if len(pages.Services) == 0 {
|
||||
t.Fatal("no service pages are configured")
|
||||
}
|
||||
// S3 is deliberately unpublished: Predastore serves that surface, so the
|
||||
// gateway dispatch tables hold no honest number for it.
|
||||
if _, ok := pages.Services[S3]; ok {
|
||||
t.Error("S3 has page metadata but no enumerable coverage to publish")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,33 +142,28 @@ func TestRenderServicePageRejectsIntroOpeningASection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderServicePageStatesOpaqueCoverage(t *testing.T) {
|
||||
// An opaque service has no dispatch table to count, so publishing a page for it
|
||||
// would report 0% where the truth is that the surface is served elsewhere.
|
||||
func TestRenderServicePageRefusesOpaqueCoverage(t *testing.T) {
|
||||
pages := testPageSet(t)
|
||||
coverage, err := CompareOperations(S3, DispatchInventory{
|
||||
coverage, err := CompareOperations(STS, DispatchInventory{
|
||||
Opaque: true,
|
||||
Note: "Predastore serves this surface.",
|
||||
Note: "Served elsewhere.",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
page, err := RenderServicePage(coverage, pages, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(page, "not mechanically enumerable: Predastore serves this surface.") {
|
||||
t.Errorf("page does not state why coverage is not enumerable:\n%s", page)
|
||||
}
|
||||
if strings.Contains(page, "### Operations") || strings.Contains(page, "%**") {
|
||||
t.Errorf("opaque page claims a percentage or an operation table:\n%s", page)
|
||||
if _, err := RenderServicePage(coverage, pages, ""); err == nil {
|
||||
t.Fatal("RenderServicePage published a page for a service with no enumerable coverage")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderIndexPageLinksEveryService(t *testing.T) {
|
||||
func TestRenderIndexPageLinksEveryPublishedService(t *testing.T) {
|
||||
pages := testPageSet(t)
|
||||
coverages := make([]OperationCoverage, 0, len(Services()))
|
||||
for _, service := range Services() {
|
||||
coverage, err := CompareOperations(service, DispatchInventory{Opaque: true, Note: "not measured here."})
|
||||
coverage, err := CompareOperations(service, DispatchInventory{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -175,7 +175,13 @@ func TestRenderIndexPageLinksEveryService(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, service := range Services() {
|
||||
page := pages.Services[service]
|
||||
page, published := pages.Services[service]
|
||||
if !published {
|
||||
if strings.Contains(index, "/docs/"+string(service)+"-api-coverage") {
|
||||
t.Errorf("index links unpublished service %q", service)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(index, "["+page.Name+"](/docs/"+page.Slug+")") {
|
||||
t.Errorf("index does not link %q at /docs/%s", page.Name, page.Slug)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user