Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All tests should use TestCheckFunc helpers #195

Merged
merged 9 commits into from May 9, 2022
2 changes: 1 addition & 1 deletion .go-version
@@ -1 +1 @@
1.17.8
1.17.9
25 changes: 5 additions & 20 deletions README.md
Expand Up @@ -66,28 +66,13 @@ If [running tests and acceptance tests](#testing) isn't enough, it's possible to
to use a development builds of the provider. This can be achieved by leveraging the Terraform CLI
[configuration file development overrides](https://www.terraform.io/cli/config/config-file#development-overrides-for-provider-developers).

First, use `make install` to place a fresh development build of the provider in your [`${GOBIN}`](https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies) (defaults to `${GOPATH}/bin` or `${HOME}/go/bin` if `${GOPATH}` is not set). Repeat
First, use `make install` to place a fresh development build of the provider in your
[`${GOBIN}`](https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies)
(defaults to `${GOPATH}/bin` or `${HOME}/go/bin` if `${GOPATH}` is not set). Repeat
this every time you make changes to the provider locally.

Then, in your `${HOME}/.terraformrc` (Unix) / `%APPDATA%\terraform.rc` (Windows), a `provider_installation` that contains
the following `dev_overrides`:

```hcl
provider_installation {
dev_overrides {
"hashicorp/tls" = "${GOBIN}" //< replace `${GOBIN}` with the actual path on your system
}

direct {}
}
```

Note that it's also possible to use a dedicated Terraform configuration file and invoke `terraform` while setting
the environment variable `TF_CLI_CONFIG_FILE=my_terraform_config_file`.

Once the `dev_overrides` are in place, any local execution of `terraform plan` and `terraform apply` will
use the version of the provider found in the given `${GOBIN}` directory,
instead of the one indicated in your terraform configuration.
Then, setup your environment following [these instructions](https://www.terraform.io/plugin/debugging#terraform-cli-development-overrides)
to make your local terraform use your local build.

### Testing GitHub Actions

Expand Down
3 changes: 2 additions & 1 deletion internal/openssh/lib_test.go
Expand Up @@ -7,8 +7,9 @@ import (
"crypto/rand"
"crypto/rsa"
"encoding/pem"
"golang.org/x/crypto/ssh"
"testing"

"golang.org/x/crypto/ssh"
)

func TestOpenSSHFormat_MarshalAndUnmarshal_RSA(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/data_source_public_key_test.go
Expand Up @@ -36,6 +36,7 @@ func TestAccPublicKey_dataSource_PEM(t *testing.T) {
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_pem", strings.TrimSpace(testPublicKeyPEM)+"\n"),
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_openssh", strings.TrimSpace(testPublicKeyOpenSSH)+"\n"),
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_fingerprint_md5", strings.TrimSpace(testPublicKeyOpenSSHFingerprintMD5)),
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_fingerprint_sha256", strings.TrimSpace(testPublicKeyOpenSSHFingerprintSHA256)),
resource.TestCheckResourceAttr("data.tls_public_key.test", "algorithm", "RSA"),
),
},
Expand Down Expand Up @@ -89,6 +90,7 @@ func TestAccPublicKey_dataSource_OpenSSHPEM(t *testing.T) {
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_pem", strings.TrimSpace(testPublicKeyPEM)+"\n"),
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_openssh", strings.TrimSpace(testPublicKeyOpenSSH)+"\n"),
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_fingerprint_md5", strings.TrimSpace(testPublicKeyOpenSSHFingerprintMD5)),
resource.TestCheckResourceAttr("data.tls_public_key.test", "public_key_fingerprint_sha256", strings.TrimSpace(testPublicKeyOpenSSHFingerprintSHA256)),
resource.TestCheckResourceAttr("data.tls_public_key.test", "algorithm", "RSA"),
),
},
Expand Down
5 changes: 3 additions & 2 deletions internal/provider/fixtures_test.go
Expand Up @@ -65,8 +65,9 @@ RhFs18D3wBDBqXLIoP7W3rm5S292/JiNPa+mX76IYFF416zTBGG9J5w4d4VFrROn
8IuMWqHgdXsCUf2szN7EnJcVBsBzTxxWqz4DjX315vbm/PFOLlKzC0Ngs4h1iDiC
D9Hk2MajZuFnJiqj1QIDAQAB
-----END PUBLIC KEY-----`
testPublicKeyOpenSSH = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDPLaq43D9C596ko9yQipWUf2FbRhFs18D3wBDBqXLIoP7W3rm5S292/JiNPa+mX76IYFF416zTBGG9J5w4d4VFrROn8IuMWqHgdXsCUf2szN7EnJcVBsBzTxxWqz4DjX315vbm/PFOLlKzC0Ngs4h1iDiCD9Hk2MajZuFnJiqj1Q==`
testPublicKeyOpenSSHFingerprintMD5 = `62:c2:c6:7a:d0:27:72:e7:0d:bc:4e:97:42:0e:9e:e6`
testPublicKeyOpenSSH = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDPLaq43D9C596ko9yQipWUf2FbRhFs18D3wBDBqXLIoP7W3rm5S292/JiNPa+mX76IYFF416zTBGG9J5w4d4VFrROn8IuMWqHgdXsCUf2szN7EnJcVBsBzTxxWqz4DjX315vbm/PFOLlKzC0Ngs4h1iDiCD9Hk2MajZuFnJiqj1Q==`
testPublicKeyOpenSSHFingerprintMD5 = `62:c2:c6:7a:d0:27:72:e7:0d:bc:4e:97:42:0e:9e:e6`
testPublicKeyOpenSSHFingerprintSHA256 = `SHA256:V5XlMMAMdN4T4S2uBqiXBuI2C9VPNG2J8a5r1Vb8Vn8`

// NOTE: See ../scripts/make-test-ca.tf for a Terraform script to create the following CA Private Key and Certificate.
testCAPrivateKey = `
Expand Down
184 changes: 46 additions & 138 deletions internal/provider/resource_cert_request_test.go
@@ -1,14 +1,13 @@
package provider

import (
"crypto/x509"
"encoding/pem"
"crypto/x509/pkix"
"fmt"
"strings"
"net"
"net/url"
"testing"

r "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestCertRequest(t *testing.T) {
Expand Down Expand Up @@ -49,86 +48,41 @@ func TestCertRequest(t *testing.T) {
%s
EOT
}
output "key_pem_1" {
value = "${tls_cert_request.test1.cert_request_pem}"
}
`, testPrivateKeyPEM),
Check: func(s *terraform.State) error {
gotUntyped := s.RootModule().Outputs["key_pem_1"].Value

got, ok := gotUntyped.(string)
if !ok {
return fmt.Errorf("output for \"key_pem_1\" is not a string")
}

if !strings.HasPrefix(got, "-----BEGIN CERTIFICATE REQUEST----") {
return fmt.Errorf("key is missing CSR PEM preamble")
}
block, _ := pem.Decode([]byte(got))
csr, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return fmt.Errorf("error parsing CSR: %s", err)
}
if expected, got := "2", csr.Subject.SerialNumber; got != expected {
return fmt.Errorf("incorrect subject serial number: expected %v, got %v", expected, got)
}
if expected, got := "example.com", csr.Subject.CommonName; got != expected {
return fmt.Errorf("incorrect subject common name: expected %v, got %v", expected, got)
}
if expected, got := "Example, Inc", csr.Subject.Organization[0]; got != expected {
return fmt.Errorf("incorrect subject organization: expected %v, got %v", expected, got)
}
if expected, got := "Department of Terraform Testing", csr.Subject.OrganizationalUnit[0]; got != expected {
return fmt.Errorf("incorrect subject organizational unit: expected %v, got %v", expected, got)
}
if expected, got := "5879 Cotton Link", csr.Subject.StreetAddress[0]; got != expected {
return fmt.Errorf("incorrect subject street address: expected %v, got %v", expected, got)
}
if expected, got := "Pirate Harbor", csr.Subject.Locality[0]; got != expected {
return fmt.Errorf("incorrect subject locality: expected %v, got %v", expected, got)
}
if expected, got := "CA", csr.Subject.Province[0]; got != expected {
return fmt.Errorf("incorrect subject province: expected %v, got %v", expected, got)
}
if expected, got := "US", csr.Subject.Country[0]; got != expected {
return fmt.Errorf("incorrect subject country: expected %v, got %v", expected, got)
}
if expected, got := "95559-1227", csr.Subject.PostalCode[0]; got != expected {
return fmt.Errorf("incorrect subject postal code: expected %v, got %v", expected, got)
}

if expected, got := 2, len(csr.DNSNames); got != expected {
return fmt.Errorf("incorrect number of DNS names: expected %v, got %v", expected, got)
}
if expected, got := "example.com", csr.DNSNames[0]; got != expected {
return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got)
}
if expected, got := "example.net", csr.DNSNames[1]; got != expected {
return fmt.Errorf("incorrect DNS name 0: expected %v, got %v", expected, got)
}

if expected, got := 2, len(csr.IPAddresses); got != expected {
return fmt.Errorf("incorrect number of IP addresses: expected %v, got %v", expected, got)
}
if expected, got := "127.0.0.1", csr.IPAddresses[0].String(); got != expected {
return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got)
}
if expected, got := "127.0.0.2", csr.IPAddresses[1].String(); got != expected {
return fmt.Errorf("incorrect IP address 0: expected %v, got %v", expected, got)
}

if expected, got := 2, len(csr.URIs); got != expected {
return fmt.Errorf("incorrect number of URIs: expected %v, got %v", expected, got)
}
if expected, got := "spiffe://example-trust-domain/workload", csr.URIs[0].String(); got != expected {
return fmt.Errorf("incorrect URI 0: expected %v, got %v", expected, got)
}
if expected, got := "spiffe://example-trust-domain/workload2", csr.URIs[1].String(); got != expected {
return fmt.Errorf("incorrect URI 1: expected %v, got %v", expected, got)
}

return nil
},
Check: r.ComposeAggregateTestCheckFunc(
testCheckPEMFormat("tls_cert_request.test1", "cert_request_pem", PreambleCertificateRequest),
testCheckPEMCertificateRequestSubject("tls_cert_request.test1", "cert_request_pem", &pkix.Name{
SerialNumber: "2",
CommonName: "example.com",
Organization: []string{"Example, Inc"},
OrganizationalUnit: []string{"Department of Terraform Testing"},
StreetAddress: []string{"5879 Cotton Link"},
Locality: []string{"Pirate Harbor"},
Province: []string{"CA"},
Country: []string{"US"},
PostalCode: []string{"95559-1227"},
}),
testCheckPEMCertificateRequestDNSNames("tls_cert_request.test1", "cert_request_pem", []string{
"example.com",
"example.net",
}),
testCheckPEMCertificateRequestIPAddresses("tls_cert_request.test1", "cert_request_pem", []net.IP{
net.ParseIP("127.0.0.1"),
net.ParseIP("127.0.0.2"),
}),
testCheckPEMCertificateRequestURIs("tls_cert_request.test1", "cert_request_pem", []*url.URL{
{
Scheme: "spiffe",
Host: "example-trust-domain",
Path: "workload",
},
{
Scheme: "spiffe",
Host: "example-trust-domain",
Path: "workload2",
},
}),
),
},
{
Config: fmt.Sprintf(`
Expand All @@ -141,62 +95,16 @@ EOT
%s
EOT
}
output "key_pem_2" {
value = "${tls_cert_request.test2.cert_request_pem}"
}
`, testPrivateKeyPEM),
Check: func(s *terraform.State) error {
gotUntyped := s.RootModule().Outputs["key_pem_2"].Value

got, ok := gotUntyped.(string)
if !ok {
return fmt.Errorf("output for \"key_pem_2\" is not a string")
}

if !strings.HasPrefix(got, "-----BEGIN CERTIFICATE REQUEST----") {
return fmt.Errorf("key is missing CSR PEM preamble")
}
block, _ := pem.Decode([]byte(got))
csr, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return fmt.Errorf("error parsing CSR: %s", err)
}
if expected, got := "42", csr.Subject.SerialNumber; got != expected {
return fmt.Errorf("incorrect subject serial number: expected %v, got %v", expected, got)
}
if expected, got := "", csr.Subject.CommonName; got != expected {
return fmt.Errorf("incorrect subject common name: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.Organization); got != expected {
return fmt.Errorf("incorrect subject organization: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.OrganizationalUnit); got != expected {
return fmt.Errorf("incorrect subject organizational unit: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.StreetAddress); got != expected {
return fmt.Errorf("incorrect subject street address: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.Locality); got != expected {
return fmt.Errorf("incorrect subject locality: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.Province); got != expected {
return fmt.Errorf("incorrect subject province: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.Country); got != expected {
return fmt.Errorf("incorrect subject country: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.Subject.PostalCode); got != expected {
return fmt.Errorf("incorrect subject postal code: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.DNSNames); got != expected {
return fmt.Errorf("incorrect number of DNS names: expected %v, got %v", expected, got)
}
if expected, got := 0, len(csr.IPAddresses); got != expected {
return fmt.Errorf("incorrect number of IP addresses: expected %v, got %v", expected, got)
}

return nil
},
Check: r.ComposeAggregateTestCheckFunc(
testCheckPEMFormat("tls_cert_request.test2", "cert_request_pem", PreambleCertificateRequest),
testCheckPEMCertificateRequestSubject("tls_cert_request.test2", "cert_request_pem", &pkix.Name{
SerialNumber: "42",
}),
testCheckPEMCertificateRequestDNSNames("tls_cert_request.test2", "cert_request_pem", []string{}),
testCheckPEMCertificateRequestIPAddresses("tls_cert_request.test2", "cert_request_pem", []net.IP{}),
testCheckPEMCertificateRequestURIs("tls_cert_request.test2", "cert_request_pem", []*url.URL{}),
),
},
},
})
Expand Down