Skip to content

Commit

Permalink
testing: fix test flake in data.nomad_allocations test (#502)
Browse files Browse the repository at this point in the history
The acceptance test for `data.nomad_allocations` creates a job and then reads
the allocations in the same configuration. This results in frequent test flakes
because registering a job via `resource.nomad_job` will typically return before
the allocations have actually been created, making the `depends_on` useless.

This frankly isn't a good workflow to encourage, as allocations are
ephemeral. Fix the test by creating the job first, waiting for the allocations
to be live, and then adding the `data.nomad_allocations` object to the config.
  • Loading branch information
tgross authored Jan 17, 2025
1 parent 251a528 commit c722c62
Showing 1 changed file with 60 additions and 2 deletions.
62 changes: 60 additions & 2 deletions nomad/data_source_allocations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
package nomad

import (
"errors"
"fmt"
"regexp"
"testing"
"time"

"github.com/hashicorp/nomad/api"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/shoenig/test/must"
"github.com/shoenig/test/wait"
)

func TestDataSourceAllocations_basic(t *testing.T) {
Expand All @@ -20,9 +24,15 @@ func TestDataSourceAllocations_basic(t *testing.T) {
Providers: testProviders,
PreCheck: func() { testAccPreCheck(t) },
Steps: []resource.TestStep{
{
Config: testDataSourceAllocations_basicConfig_jobOnly(name),
},
{
Config: testDataSourceAllocations_basicConfig(name),
Check: resource.ComposeTestCheckFunc(

testDataSourceAllocations_waitForAllocs(t, 3),

resource.TestCheckResourceAttrSet("data.nomad_allocations.all", "allocations.#"),
resource.TestCheckResourceAttr("data.nomad_allocations.by_job", "allocations.#", "3"),
func(s *terraform.State) error {
Expand Down Expand Up @@ -63,7 +73,7 @@ func TestDataSourceAllocations_basic(t *testing.T) {
})
}

func testDataSourceAllocations_basicConfig(prefix string) string {
func testDataSourceAllocations_basicConfig_jobOnly(prefix string) string {
return fmt.Sprintf(`
resource "nomad_job" "test" {
jobspec = <<EOT
Expand Down Expand Up @@ -93,6 +103,12 @@ resource "nomad_job" "test" {
}
EOT
}
`, prefix)
}

func testDataSourceAllocations_basicConfig(prefix string) string {
return fmt.Sprintf(`
%s
data "nomad_allocations" "all" {
depends_on = [nomad_job.test]
Expand All @@ -101,5 +117,47 @@ data "nomad_allocations" "all" {
data "nomad_allocations" "by_job" {
filter = "JobID == \"${nomad_job.test.id}\""
}
`, prefix)
`, testDataSourceAllocations_basicConfig_jobOnly(prefix))
}

func testDataSourceAllocations_waitForAllocs(t *testing.T, expected int) resource.TestCheckFunc {
return func(s *terraform.State) error {

resourceState := s.Modules[0].Resources["nomad_job.test"]
if resourceState == nil {
return errors.New("job resource not found in state")
}

instanceState := resourceState.Primary
if instanceState == nil {
return errors.New("job resource has no primary instance")
}

jobID := instanceState.ID

ns, ok := instanceState.Attributes["namespace"]
if !ok {
return errors.New("resource does not have expected namespace")
}

providerConfig := testProvider.Meta().(ProviderConfig)
client := providerConfig.client

must.Wait(t, wait.InitialSuccess(
wait.ErrorFunc(func() error {
allocs, _, err := client.Jobs().Allocations(
jobID, true, &api.QueryOptions{Namespace: ns})
must.NoError(t, err)
if len(allocs) != expected {
return fmt.Errorf("expected %d allocs, got %d", expected, len(allocs))
}
t.Logf("got 3 allocs")
return nil
}),
wait.Timeout(10*time.Second),
wait.Gap(100*time.Millisecond),
))

return nil
}
}

0 comments on commit c722c62

Please sign in to comment.