Skip to content

fix: include provisioner timing action in hash func #14388

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

Merged
merged 1 commit into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
A resource can transition through multiple states through actions like 'delete' and 'create'.
Previously we were not including the action in the 'hashByState' function, leading to missed timings.
See 'docker_container.workspace[0]' below.

-- apply --
{"@level":"info","@message":"Terraform 1.9.2","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:39.724076+02:00","terraform":"1.9.2","type":"version","ui":"1.2"}
{"@level":"info","@message":"data.coder_parameter.memory_size: Refreshing...","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.003696+02:00","hook":{"resource":{"addr":"data.coder_parameter.memory_size","module":"","resource":"data.coder_parameter.memory_size","implied_provider":"coder","resource_type":"coder_parameter","resource_name":"memory_size","resource_key":null},"action":"read"},"type":"apply_start"}
{"@level":"info","@message":"data.coder_workspace.me: Refreshing...","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.003703+02:00","hook":{"resource":{"addr":"data.coder_workspace.me","module":"","resource":"data.coder_workspace.me","implied_provider":"coder","resource_type":"coder_workspace","resource_name":"me","resource_key":null},"action":"read"},"type":"apply_start"}
{"@level":"info","@message":"data.coder_provisioner.me: Refreshing...","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.003711+02:00","hook":{"resource":{"addr":"data.coder_provisioner.me","module":"","resource":"data.coder_provisioner.me","implied_provider":"coder","resource_type":"coder_provisioner","resource_name":"me","resource_key":null},"action":"read"},"type":"apply_start"}
{"@level":"info","@message":"data.http.latest_commit: Refreshing...","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.003786+02:00","hook":{"resource":{"addr":"data.http.latest_commit","module":"","resource":"data.http.latest_commit","implied_provider":"http","resource_type":"http","resource_name":"latest_commit","resource_key":null},"action":"read"},"type":"apply_start"}
{"@level":"info","@message":"data.coder_provisioner.me: Refresh complete after 0s [id=6c107654-0d6d-400f-bd54-5dd3eb7c0ecd]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.004366+02:00","hook":{"resource":{"addr":"data.coder_provisioner.me","module":"","resource":"data.coder_provisioner.me","implied_provider":"coder","resource_type":"coder_provisioner","resource_name":"me","resource_key":null},"action":"read","id_key":"id","id_value":"6c107654-0d6d-400f-bd54-5dd3eb7c0ecd","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"data.coder_workspace.me: Refresh complete after 0s [id=5509156c-f08e-4524-8eb5-51ff595226fb]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.004689+02:00","hook":{"resource":{"addr":"data.coder_workspace.me","module":"","resource":"data.coder_workspace.me","implied_provider":"coder","resource_type":"coder_workspace","resource_name":"me","resource_key":null},"action":"read","id_key":"id","id_value":"5509156c-f08e-4524-8eb5-51ff595226fb","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"data.coder_parameter.memory_size: Refresh complete after 0s [id=1be91971-33dd-4eb8-a1a3-0ba3a38a8dde]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.004938+02:00","hook":{"resource":{"addr":"data.coder_parameter.memory_size","module":"","resource":"data.coder_parameter.memory_size","implied_provider":"coder","resource_type":"coder_parameter","resource_name":"memory_size","resource_key":null},"action":"read","id_key":"id","id_value":"1be91971-33dd-4eb8-a1a3-0ba3a38a8dde","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"coder_agent.main: Refreshing state... [id=9a62f453-6303-4d10-99d4-9001f73683c2]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.007139+02:00","hook":{"resource":{"addr":"coder_agent.main","module":"","resource":"coder_agent.main","implied_provider":"coder","resource_type":"coder_agent","resource_name":"main","resource_key":null},"id_key":"id","id_value":"9a62f453-6303-4d10-99d4-9001f73683c2"},"type":"refresh_start"}
{"@level":"info","@message":"docker_image.main: Refreshing state... [id=sha256:443d199e8bfcce69c2aa494b36b5f8b04c3b183277cd19190e9589fd8552d618nginx:latest]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.008559+02:00","hook":{"resource":{"addr":"docker_image.main","module":"","resource":"docker_image.main","implied_provider":"docker","resource_type":"docker_image","resource_name":"main","resource_key":null},"id_key":"id","id_value":"sha256:443d199e8bfcce69c2aa494b36b5f8b04c3b183277cd19190e9589fd8552d618nginx:latest"},"type":"refresh_start"}
{"@level":"info","@message":"coder_agent.main: Refresh complete [id=9a62f453-6303-4d10-99d4-9001f73683c2]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.011774+02:00","hook":{"resource":{"addr":"coder_agent.main","module":"","resource":"coder_agent.main","implied_provider":"coder","resource_type":"coder_agent","resource_name":"main","resource_key":null},"id_key":"id","id_value":"9a62f453-6303-4d10-99d4-9001f73683c2"},"type":"refresh_complete"}
{"@level":"info","@message":"docker_volume.home_volume: Refreshing state... [id=coder-57e02f44-3b83-4f24-ac6f-65376cc5ab8e-home]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.011801+02:00","hook":{"resource":{"addr":"docker_volume.home_volume","module":"","resource":"docker_volume.home_volume","implied_provider":"docker","resource_type":"docker_volume","resource_name":"home_volume","resource_key":null},"id_key":"id","id_value":"coder-57e02f44-3b83-4f24-ac6f-65376cc5ab8e-home"},"type":"refresh_start"}
{"@level":"info","@message":"coder_script.startup_script: Refreshing state... [id=46d825ef-dd7e-47b6-a8e0-cda5d7695e0e]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.015683+02:00","hook":{"resource":{"addr":"coder_script.startup_script","module":"","resource":"coder_script.startup_script","implied_provider":"coder","resource_type":"coder_script","resource_name":"startup_script","resource_key":null},"id_key":"id","id_value":"46d825ef-dd7e-47b6-a8e0-cda5d7695e0e"},"type":"refresh_start"}
{"@level":"info","@message":"coder_script.startup_script: Refresh complete [id=46d825ef-dd7e-47b6-a8e0-cda5d7695e0e]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.016027+02:00","hook":{"resource":{"addr":"coder_script.startup_script","module":"","resource":"coder_script.startup_script","implied_provider":"coder","resource_type":"coder_script","resource_name":"startup_script","resource_key":null},"id_key":"id","id_value":"46d825ef-dd7e-47b6-a8e0-cda5d7695e0e"},"type":"refresh_complete"}
{"@level":"info","@message":"docker_volume.home_volume: Refresh complete [id=coder-57e02f44-3b83-4f24-ac6f-65376cc5ab8e-home]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.017694+02:00","hook":{"resource":{"addr":"docker_volume.home_volume","module":"","resource":"docker_volume.home_volume","implied_provider":"docker","resource_type":"docker_volume","resource_name":"home_volume","resource_key":null},"id_key":"id","id_value":"coder-57e02f44-3b83-4f24-ac6f-65376cc5ab8e-home"},"type":"refresh_complete"}
{"@level":"info","@message":"docker_image.main: Refresh complete [id=sha256:443d199e8bfcce69c2aa494b36b5f8b04c3b183277cd19190e9589fd8552d618nginx:latest]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.025098+02:00","hook":{"resource":{"addr":"docker_image.main","module":"","resource":"docker_image.main","implied_provider":"docker","resource_type":"docker_image","resource_name":"main","resource_key":null},"id_key":"id","id_value":"sha256:443d199e8bfcce69c2aa494b36b5f8b04c3b183277cd19190e9589fd8552d618nginx:latest"},"type":"refresh_complete"}
{"@level":"info","@message":"docker_container.workspace[0]: Refreshing state... [id=6124169bfea9b13f34ee9e730c8772e950898136cd5565f5b3343a7849573050]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.027874+02:00","hook":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"id_key":"id","id_value":"6124169bfea9b13f34ee9e730c8772e950898136cd5565f5b3343a7849573050"},"type":"refresh_start"}
{"@level":"info","@message":"data.http.latest_commit: Refresh complete after 0s [id=https://api.github.com/repos/coder/coder/commits/main]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.107958+02:00","hook":{"resource":{"addr":"data.http.latest_commit","module":"","resource":"data.http.latest_commit","implied_provider":"http","resource_type":"http","resource_name":"latest_commit","resource_key":null},"action":"read","id_key":"id","id_value":"https://api.github.com/repos/coder/coder/commits/main","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"docker_container.workspace[0]: Refresh complete [id=6124169bfea9b13f34ee9e730c8772e950898136cd5565f5b3343a7849573050]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.137794+02:00","hook":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"id_key":"id","id_value":"6124169bfea9b13f34ee9e730c8772e950898136cd5565f5b3343a7849573050"},"type":"refresh_complete"}
{"@level":"info","@message":"docker_container.workspace[0]: Drift detected (update)","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.151984+02:00","change":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"action":"update"},"type":"resource_drift"}
{"@level":"info","@message":"coder_agent.main: Drift detected (update)","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.152016+02:00","change":{"resource":{"addr":"coder_agent.main","module":"","resource":"coder_agent.main","implied_provider":"coder","resource_type":"coder_agent","resource_name":"main","resource_key":null},"action":"update"},"type":"resource_drift"}
{"@level":"info","@message":"docker_container.workspace[0]: Plan to replace","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.152023+02:00","change":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"action":"replace","reason":"cannot_update"},"type":"planned_change"}
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 1 to destroy.","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.152028+02:00","changes":{"add":1,"change":0,"import":0,"remove":1,"operation":"plan"},"type":"change_summary"}
{"@level":"info","@message":"docker_container.workspace[0]: Destroying... [id=6124169bfea9b13f34ee9e730c8772e950898136cd5565f5b3343a7849573050]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.204215+02:00","hook":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"action":"delete","id_key":"id","id_value":"6124169bfea9b13f34ee9e730c8772e950898136cd5565f5b3343a7849573050"},"type":"apply_start"}
{"@level":"info","@message":"docker_container.workspace[0]: Destruction complete after 0s","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.250903+02:00","hook":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"action":"delete","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"docker_container.workspace[0]: Creating...","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.264384+02:00","hook":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"action":"create"},"type":"apply_start"}
{"@level":"info","@message":"docker_container.workspace[0]: Creation complete after 1s [id=4c8842d427970f6ce34da73085b61deaa72bdaf14d0dc56972f5eaa93c86a2f0]","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.577054+02:00","hook":{"resource":{"addr":"docker_container.workspace[0]","module":"","resource":"docker_container.workspace[0]","implied_provider":"docker","resource_type":"docker_container","resource_name":"workspace","resource_key":0},"action":"create","id_key":"id","id_value":"4c8842d427970f6ce34da73085b61deaa72bdaf14d0dc56972f5eaa93c86a2f0","elapsed_seconds":1},"type":"apply_complete"}
{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 1 destroyed.","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.612265+02:00","changes":{"add":1,"change":0,"import":0,"remove":1,"operation":"apply"},"type":"change_summary"}
{"@level":"info","@message":"Outputs: 0","@module":"terraform.ui","@timestamp":"2024-08-21T22:59:40.612270+02:00","outputs":{},"type":"outputs"}
-- timings --
{"start":"2024-08-21T20:59:40.003696Z", "end":"2024-08-21T20:59:40.004938Z", "action":"read", "source":"coder", "resource":"data.coder_parameter.memory_size", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.003703Z", "end":"2024-08-21T20:59:40.004689Z", "action":"read", "source":"coder", "resource":"data.coder_workspace.me", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.003711Z", "end":"2024-08-21T20:59:40.004366Z", "action":"read", "source":"coder", "resource":"data.coder_provisioner.me", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.003786Z", "end":"2024-08-21T20:59:40.107958Z", "action":"read", "source":"http", "resource":"data.http.latest_commit", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.007139Z", "end":"2024-08-21T20:59:40.011774Z", "action":"state refresh", "source":"coder", "resource":"coder_agent.main", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.008559Z", "end":"2024-08-21T20:59:40.025098Z", "action":"state refresh", "source":"docker", "resource":"docker_image.main", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.011801Z", "end":"2024-08-21T20:59:40.017694Z", "action":"state refresh", "source":"docker", "resource":"docker_volume.home_volume", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.015683Z", "end":"2024-08-21T20:59:40.016027Z", "action":"state refresh", "source":"coder", "resource":"coder_script.startup_script", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.027874Z", "end":"2024-08-21T20:59:40.137794Z", "action":"state refresh", "source":"docker", "resource":"docker_container.workspace[0]", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.204215Z", "end":"2024-08-21T20:59:40.250903Z", "action":"delete", "source":"docker", "resource":"docker_container.workspace[0]", "stage":"apply", "state":"COMPLETED"}
{"start":"2024-08-21T20:59:40.264384Z", "end":"2024-08-21T20:59:40.577054Z", "action":"create", "source":"docker", "resource":"docker_container.workspace[0]", "stage":"apply", "state":"COMPLETED"}
2 changes: 1 addition & 1 deletion provisioner/terraform/timings.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func (l timingKind) Category() string {
// hashState computes a hash based on a timingSpan's unique properties and state.
// The combination of resource and provider names MUST be unique across entries.
func (e *timingSpan) hashByState(state proto.TimingState) uint64 {
id := fmt.Sprintf("%s:%s:%s:%s", e.kind.Category(), state.String(), e.resource, e.provider)
id := fmt.Sprintf("%s:%s:%s:%s:%s", e.kind.Category(), state.String(), e.action, e.resource, e.provider)
return xxhash.Sum64String(id)
}

Expand Down
16 changes: 12 additions & 4 deletions provisioner/terraform/timings_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ var (
inputIncomplete []byte
//go:embed testdata/timings-aggregation/faster-than-light.txtar
inputFasterThanLight []byte
//go:embed testdata/timings-aggregation/multiple-resource-actions.txtar
multipleResourceActions []byte
)

func TestAggregation(t *testing.T) {
Expand Down Expand Up @@ -63,6 +65,10 @@ func TestAggregation(t *testing.T) {
name: "faster-than-light",
input: inputFasterThanLight,
},
{
name: "multiple-resource-actions",
input: multipleResourceActions,
},
}

// nolint:paralleltest // Not since go v1.22.
Expand Down Expand Up @@ -101,7 +107,10 @@ func TestAggregation(t *testing.T) {
expected := terraform_internal.ParseTimingLines(t, expectedTimings.Data)
terraform_internal.StableSortTimings(t, actualTimings) // To reduce flakiness.
if !assert.True(t, terraform_internal.TimingsAreEqual(t, expected, actualTimings)) {
printExpectation(t, expected)
t.Log("expected:")
printTimings(t, expected)
t.Log("actual:")
printTimings(t, actualTimings)
}
})
}
Expand Down Expand Up @@ -133,11 +142,10 @@ func ingestAllSpans(t *testing.T, input []byte, aggregator *timingAggregator) {
require.NoError(t, scanner.Err())
}

func printExpectation(t *testing.T, actual []*proto.Timing) {
func printTimings(t *testing.T, timings []*proto.Timing) {
t.Helper()

t.Log("expected:")
for _, a := range actual {
for _, a := range timings {
terraform_internal.PrintTiming(t, a)
}
}
Loading