package host import ( "context" "errors" "os" "testing" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials" awss3 "github.com/aws/aws-sdk-go-v2/service/s3" s3types "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/aws/smithy-go" ) // TestT4StorageProbeMinio runs T4's store probe (§7.3, §14.1) against a // real S3 server: with the delivered variables of a bound store it lists, // puts, gets and deletes .carlos-move-probe/ and leaves nothing; // with wrong credentials T4 fails with the store's sentence. It runs only // where .amadan/ci.d/30-minio-contract stands a MinIO up (CARLOS_MINIO_TEST // and the MINIO_* variables, as TestDeliveredContractMinio reads them). func TestT4StorageProbeMinio(t *testing.T) { if os.Getenv("CARLOS_MINIO_TEST") != "1" { t.Skip("set CARLOS_MINIO_TEST=1 (with a running MinIO and the MINIO_* env vars) to run the T4 probe test; see .amadan/ci.d/30-minio-contract") } need := func(name string) string { v := os.Getenv(name) if v == "" { t.Fatalf("%s is not set", name) } return v } endpoint, key, secret, bucket := need("MINIO_ENDPOINT"), need("MINIO_SCOPED_KEY"), need("MINIO_SCOPED_SECRET"), need("MINIO_BUCKET") ctx := context.Background() env := map[string]string{ "STORE_BUCKET": bucket, "STORE_ENDPOINT": endpoint, "STORE_REGION": "us-east-1", "STORE_ACCESS_KEY": key, "STORE_SECRET_KEY": secret, } if prefix, err := probeStores(ctx, env, p1ID); err != nil { t.Fatalf("probe of %s: %v", prefix, err) } // The probe object is gone. c := awss3.New(awss3.Options{ Region: "us-east-1", Credentials: credentials.NewStaticCredentialsProvider(key, secret, ""), BaseEndpoint: aws.String(endpoint), UsePathStyle: true, RequestChecksumCalculation: aws.RequestChecksumCalculationWhenRequired, ResponseChecksumValidation: aws.ResponseChecksumValidationWhenRequired, }) _, err := c.HeadObject(ctx, &awss3.HeadObjectInput{Bucket: aws.String(bucket), Key: aws.String(".carlos-move-probe/" + p1ID)}) // Only a not-found answer proves it is gone: AccessDenied or any other // error says nothing about the object. var apiErr smithy.APIError var notFound *s3types.NotFound if err == nil || !(errors.As(err, ¬Found) || (errors.As(err, &apiErr) && (apiErr.ErrorCode() == "NotFound" || apiErr.ErrorCode() == "NoSuchKey"))) { t.Fatalf("the probe object is not shown gone (head: %v)", err) } // Wrong credentials: T4 fails with the store's sentence. env["STORE_SECRET_KEY"] = "not-the-secret" w := &movesWorker{cfg: moveCfg{ProbeStore: probeStores}} got := w.checkStorage(ctx, heldEnv{env: env}, p1ID) if got.OK || got.Reason != t4Failed("STORE") { t.Fatalf("T4 with wrong credentials = %+v", got) } }