@@ -312,6 +312,88 @@ func TestPrimary_stateStore(t *testing.T) {
312312 }
313313}
314314
315+ func TestPrimary_stateStore_planFile (t * testing.T ) {
316+
317+ if ! canRunGoBuild {
318+ // We're running in a separate-build-then-run context, so we can't
319+ // currently execute this test which depends on being able to build
320+ // new executable at runtime.
321+ //
322+ // (See the comment on canRunGoBuild's declaration for more information.)
323+ t .Skip ("can't run without building a new provider executable" )
324+ }
325+
326+ t .Setenv (e2e .TestExperimentFlag , "true" )
327+ terraformBin := e2e .GoBuild ("github.com/hashicorp/terraform" , "terraform" )
328+
329+ fixturePath := filepath .Join ("testdata" , "full-workflow-with-state-store-fs" )
330+ tf := e2e .NewBinary (t , terraformBin , fixturePath )
331+
332+ // In order to test integration with PSS we need a provider plugin implementing a state store.
333+ // Here will build the simple6 (built with protocol v6) provider, which implements PSS.
334+ simple6Provider := filepath .Join (tf .WorkDir (), "terraform-provider-simple6" )
335+ simple6ProviderExe := e2e .GoBuild ("github.com/hashicorp/terraform/internal/provider-simple-v6/main" , simple6Provider )
336+
337+ // Move the provider binaries into a directory that we will point terraform
338+ // to using the -plugin-dir cli flag.
339+ platform := getproviders .CurrentPlatform .String ()
340+ hashiDir := "cache/registry.terraform.io/hashicorp/"
341+ if err := os .MkdirAll (tf .Path (hashiDir , "simple6/0.0.1/" , platform ), os .ModePerm ); err != nil {
342+ t .Fatal (err )
343+ }
344+ if err := os .Rename (simple6ProviderExe , tf .Path (hashiDir , "simple6/0.0.1/" , platform , "terraform-provider-simple6" )); err != nil {
345+ t .Fatal (err )
346+ }
347+
348+ //// INIT
349+ stdout , stderr , err := tf .Run ("init" , "-enable-pluggable-state-storage-experiment=true" , "-plugin-dir=cache" , "-no-color" )
350+ if err != nil {
351+ t .Fatalf ("unexpected init error: %s\n stderr:\n %s" , err , stderr )
352+ }
353+
354+ if ! strings .Contains (stdout , "Terraform created an empty state file for the default workspace" ) {
355+ t .Errorf ("notice about creating the default workspace is missing from init output:\n %s" , stdout )
356+ }
357+
358+ //// PLAN
359+ planFile := "testplan"
360+ stdout , stderr , err = tf .Run ("plan" , "-out=" + planFile , "-no-color" )
361+ if err != nil {
362+ t .Fatalf ("unexpected apply error: %s\n stderr:\n %s" , err , stderr )
363+ }
364+
365+ //// APPLY
366+ stdout , stderr , err = tf .Run ("apply" , "-auto-approve" , "-no-color" , planFile )
367+ if err != nil {
368+ t .Fatalf ("unexpected apply error: %s\n stderr:\n %s" , err , stderr )
369+ }
370+
371+ if ! strings .Contains (stdout , "Resources: 1 added, 0 changed, 0 destroyed" ) {
372+ t .Errorf ("incorrect apply tally; want 1 added:\n %s" , stdout )
373+ }
374+
375+ // Check the statefile saved by the fs state store.
376+ path := "terraform.tfstate.d/default/terraform.tfstate"
377+ f , err := tf .OpenFile (path )
378+ if err != nil {
379+ t .Fatalf ("unexpected error opening state file %s: %s\n stderr:\n %s" , path , err , stderr )
380+ }
381+ defer f .Close ()
382+
383+ stateFile , err := statefile .Read (f )
384+ if err != nil {
385+ t .Fatalf ("unexpected error reading statefile %s: %s\n stderr:\n %s" , path , err , stderr )
386+ }
387+
388+ r := stateFile .State .RootModule ().Resources
389+ if len (r ) != 1 {
390+ t .Fatalf ("expected state to include one resource, but got %d" , len (r ))
391+ }
392+ if _ , ok := r ["terraform_data.my-data" ]; ! ok {
393+ t .Fatalf ("expected state to include terraform_data.my-data but it's missing" )
394+ }
395+ }
396+
315397func TestPrimary_stateStore_inMem (t * testing.T ) {
316398 if ! canRunGoBuild {
317399 // We're running in a separate-build-then-run context, so we can't
0 commit comments