Refactor E2E tests to use new reattached provider test helper (#38643)

* test: Update reattachedProviderForTest to return the provider server used, so tests can choose to make assertions against it. Refactor relevant E2E tests to use new reattachedProviderForTest helper function.
pull/38634/head^2
Sarah French 2 weeks ago committed by GitHub
parent 8410263caa
commit 95db2b28ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5,11 +5,8 @@ package e2etest
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"path"
"path/filepath"
@ -17,18 +14,12 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/e2e"
"github.com/hashicorp/terraform/internal/getproviders"
"github.com/hashicorp/terraform/internal/grpcwrap"
tfplugin "github.com/hashicorp/terraform/internal/plugin6"
simple "github.com/hashicorp/terraform/internal/provider-simple-v6"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/states/statefile"
proto "github.com/hashicorp/terraform/internal/tfplugin6"
)
// Test that users can do the full init-plan-apply workflow with pluggable state storage
@ -51,55 +42,7 @@ func TestPrimary_stateStore_unmanaged_separatePlan(t *testing.T) {
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
reattachCh := make(chan *plugin.ReattachConfig)
closeCh := make(chan struct{})
provider := &providerServer{
ProviderServer: grpcwrap.Provider6(simple.Provider()),
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go plugin.Serve(&plugin.ServeConfig{
Logger: hclog.New(&hclog.LoggerOptions{
Name: "plugintest",
Level: hclog.Trace,
Output: io.Discard,
}),
Test: &plugin.ServeTestConfig{
Context: ctx,
ReattachConfigCh: reattachCh,
CloseCh: closeCh,
},
GRPCServer: plugin.DefaultGRPCServer,
VersionedPlugins: map[int]plugin.PluginSet{
6: {
"provider": &tfplugin.GRPCProviderPlugin{
GRPCProvider: func() proto.ProviderServer {
return provider
},
},
},
},
})
config := <-reattachCh
if config == nil {
t.Fatalf("no reattach config received")
}
reattachStr, err := json.Marshal(map[string]reattachConfig{
"hashicorp/simple6": {
Protocol: string(config.Protocol),
ProtocolVersion: 6,
Pid: config.Pid,
Test: true,
Addr: reattachConfigAddr{
Network: config.Addr.Network(),
String: config.Addr.String(),
},
},
})
if err != nil {
t.Fatal(err)
}
reattachStr, provider := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
// Required for the local state files to be written to the temp directory,
@ -165,9 +108,6 @@ func TestPrimary_stateStore_unmanaged_separatePlan(t *testing.T) {
if err != nil {
t.Fatalf("unexpected destroy error: %s\nstderr:\n%s\nstdout:\n%s", err, stderr, stdout)
}
cancel()
<-closeCh
}
// Tests using `terraform workspace` commands in combination with pluggable state storage.

@ -4,10 +4,7 @@
package e2etest
import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"reflect"
@ -16,18 +13,13 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/command"
"github.com/hashicorp/terraform/internal/command/clistate"
"github.com/hashicorp/terraform/internal/e2e"
"github.com/hashicorp/terraform/internal/getproviders"
"github.com/hashicorp/terraform/internal/grpcwrap"
"github.com/hashicorp/terraform/internal/plans"
tfplugin "github.com/hashicorp/terraform/internal/plugin6"
simple "github.com/hashicorp/terraform/internal/provider-simple-v6"
"github.com/hashicorp/terraform/internal/states/statefile"
proto "github.com/hashicorp/terraform/internal/tfplugin6"
"github.com/zclconf/go-cty/cty"
)
@ -422,56 +414,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenInitAndPlanApply(t *te
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
reattachCh := make(chan *plugin.ReattachConfig)
closeCh := make(chan struct{})
provider := &providerServer{
ProviderServer: grpcwrap.Provider6(simple.Provider()),
}
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
go plugin.Serve(&plugin.ServeConfig{
Logger: hclog.New(&hclog.LoggerOptions{
Name: "plugintest",
Level: hclog.Trace,
Output: io.Discard,
}),
Test: &plugin.ServeTestConfig{
Context: ctx,
ReattachConfigCh: reattachCh,
CloseCh: closeCh,
},
GRPCServer: plugin.DefaultGRPCServer,
VersionedPlugins: map[int]plugin.PluginSet{
6: {
"provider": &tfplugin.GRPCProviderPlugin{
GRPCProvider: func() proto.ProviderServer {
return provider
},
},
},
},
})
config := <-reattachCh
if config == nil {
t.Fatalf("no reattach config received")
}
reattachStr, err := json.Marshal(map[string]reattachConfig{
"hashicorp/simple6": {
Protocol: string(config.Protocol),
ProtocolVersion: 6,
Pid: config.Pid,
Test: true,
Addr: reattachConfigAddr{
Network: config.Addr.Network(),
String: config.Addr.String(),
},
},
})
if err != nil {
t.Fatal(err)
}
reattachStr, _ := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
//// INIT - using reattached provider.
@ -758,56 +701,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenSuccessiveInits(t *tes
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
reattachCh := make(chan *plugin.ReattachConfig)
closeCh := make(chan struct{})
provider := &providerServer{
ProviderServer: grpcwrap.Provider6(simple.Provider()),
}
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
go plugin.Serve(&plugin.ServeConfig{
Logger: hclog.New(&hclog.LoggerOptions{
Name: "plugintest",
Level: hclog.Trace,
Output: io.Discard,
}),
Test: &plugin.ServeTestConfig{
Context: ctx,
ReattachConfigCh: reattachCh,
CloseCh: closeCh,
},
GRPCServer: plugin.DefaultGRPCServer,
VersionedPlugins: map[int]plugin.PluginSet{
6: {
"provider": &tfplugin.GRPCProviderPlugin{
GRPCProvider: func() proto.ProviderServer {
return provider
},
},
},
},
})
config := <-reattachCh
if config == nil {
t.Fatalf("no reattach config received")
}
reattachStr, err := json.Marshal(map[string]reattachConfig{
"hashicorp/simple6": {
Protocol: string(config.Protocol),
ProtocolVersion: 6,
Pid: config.Pid,
Test: true,
Addr: reattachConfigAddr{
Network: config.Addr.Network(),
String: config.Addr.String(),
},
},
})
if err != nil {
t.Fatal(err)
}
reattachStr, _ := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
//// INIT 1 - using reattached provider.

@ -450,7 +450,7 @@ func TestProviderInstall_reattached(t *testing.T) {
// Launch a separate simple6 provider process to be re-used as a reattached provider.
// Tests will use this via the TF_REATTACH_PROVIDERS environment variable.
reattachConfig := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
reattachConfig, _ := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
t.Run("reattached provider not installed when provider not present in dependency lock file", func(t *testing.T) {
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
@ -624,7 +624,7 @@ provider "registry.terraform.io/hashicorp/simple6" {
// reattachedProviderForTest launches a provider process and returns a reattach config string
// that can be used as the value for the TF_REATTACH_PROVIDERS environment variable in tests.
// Cleanup of the provider process is handled internally.
func reattachedProviderForTest(t *testing.T, provider addrs.Provider, protocol int) string {
func reattachedProviderForTest(t *testing.T, provider addrs.Provider, protocol int) (string, *providerServer) {
t.Helper()
if !slices.Contains([]int{5, 6}, protocol) {
t.Fatalf("test setup tried to create a provider using protocol version %d, which is unsupported. Choose between 5 and 6.", protocol)
@ -681,5 +681,5 @@ func reattachedProviderForTest(t *testing.T, provider addrs.Provider, protocol i
if err != nil {
t.Fatal(err)
}
return string(reattachStr)
return string(reattachStr), server
}

@ -5,21 +5,13 @@ package e2etest
import (
"context"
"encoding/json"
"io"
"path/filepath"
"strings"
"sync"
"testing"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/e2e"
"github.com/hashicorp/terraform/internal/grpcwrap"
tfplugin5 "github.com/hashicorp/terraform/internal/plugin"
tfplugin "github.com/hashicorp/terraform/internal/plugin6"
simple5 "github.com/hashicorp/terraform/internal/provider-simple"
simple "github.com/hashicorp/terraform/internal/provider-simple-v6"
proto5 "github.com/hashicorp/terraform/internal/tfplugin5"
proto "github.com/hashicorp/terraform/internal/tfplugin6"
)
@ -234,55 +226,7 @@ func TestUnmanagedSeparatePlan(t *testing.T) {
fixturePath := filepath.Join("testdata", "test-provider")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
reattachCh := make(chan *plugin.ReattachConfig)
closeCh := make(chan struct{})
provider := &providerServer{
ProviderServer: grpcwrap.Provider6(simple.Provider()),
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go plugin.Serve(&plugin.ServeConfig{
Logger: hclog.New(&hclog.LoggerOptions{
Name: "plugintest",
Level: hclog.Trace,
Output: io.Discard,
}),
Test: &plugin.ServeTestConfig{
Context: ctx,
ReattachConfigCh: reattachCh,
CloseCh: closeCh,
},
GRPCServer: plugin.DefaultGRPCServer,
VersionedPlugins: map[int]plugin.PluginSet{
6: {
"provider": &tfplugin.GRPCProviderPlugin{
GRPCProvider: func() proto.ProviderServer {
return provider
},
},
},
},
})
config := <-reattachCh
if config == nil {
t.Fatalf("no reattach config received")
}
reattachStr, err := json.Marshal(map[string]reattachConfig{
"hashicorp/test": {
Protocol: string(config.Protocol),
ProtocolVersion: 6,
Pid: config.Pid,
Test: true,
Addr: reattachConfigAddr{
Network: config.Addr.Network(),
String: config.Addr.String(),
},
},
})
if err != nil {
t.Fatal(err)
}
reattachStr, provider := reattachedProviderForTest(t, addrs.NewDefaultProvider("test"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
//// INIT
@ -329,8 +273,6 @@ func TestUnmanagedSeparatePlan(t *testing.T) {
if !provider.ApplyResourceChangeCalled() {
t.Error("ApplyResourceChange (destroy) not called on in-process provider")
}
cancel()
<-closeCh
}
func TestUnmanagedSeparatePlan_proto5(t *testing.T) {
@ -339,55 +281,7 @@ func TestUnmanagedSeparatePlan_proto5(t *testing.T) {
fixturePath := filepath.Join("testdata", "test-provider")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
reattachCh := make(chan *plugin.ReattachConfig)
closeCh := make(chan struct{})
provider := &providerServer5{
ProviderServer: grpcwrap.Provider(simple5.Provider()),
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go plugin.Serve(&plugin.ServeConfig{
Logger: hclog.New(&hclog.LoggerOptions{
Name: "plugintest",
Level: hclog.Trace,
Output: io.Discard,
}),
Test: &plugin.ServeTestConfig{
Context: ctx,
ReattachConfigCh: reattachCh,
CloseCh: closeCh,
},
GRPCServer: plugin.DefaultGRPCServer,
VersionedPlugins: map[int]plugin.PluginSet{
5: {
"provider": &tfplugin5.GRPCProviderPlugin{
GRPCProvider: func() proto5.ProviderServer {
return provider
},
},
},
},
})
config := <-reattachCh
if config == nil {
t.Fatalf("no reattach config received")
}
reattachStr, err := json.Marshal(map[string]reattachConfig{
"hashicorp/test": {
Protocol: string(config.Protocol),
ProtocolVersion: 5,
Pid: config.Pid,
Test: true,
Addr: reattachConfigAddr{
Network: config.Addr.Network(),
String: config.Addr.String(),
},
},
})
if err != nil {
t.Fatal(err)
}
reattachStr, provider := reattachedProviderForTest(t, addrs.NewDefaultProvider("test"), 5) // protocol 5
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
//// INIT
@ -434,6 +328,4 @@ func TestUnmanagedSeparatePlan_proto5(t *testing.T) {
if !provider.ApplyResourceChangeCalled() {
t.Error("ApplyResourceChange (destroy) not called on in-process provider")
}
cancel()
<-closeCh
}

Loading…
Cancel
Save