Skip to content

Commit 0ef1f1a

Browse files
committed
(PDB-4832) Add test for migration 76 in isolation
This commit tests the case where the old version of migration 74 has already been applied and the idx_report_id index wasn't added to the partitions. In this case migration 76 will add the index to any existing partitions. Changing the behavior of migration 74 after the fact should be safe because the index creation is guarded by 'if not exists' in both migration 74 and 76. If we've already migrated past 74 before the change then the index will get added in 76. If someone applies both 74 and 76 at the same time 76 will then become a no-op.
1 parent 44f6922 commit 0ef1f1a

File tree

2 files changed

+63
-32
lines changed

2 files changed

+63
-32
lines changed

src/puppetlabs/puppetdb/scf/partitioning.clj

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@
111111
(format "CREATE UNIQUE INDEX IF NOT EXISTS resource_events_hash_%s ON %s (event_hash)"
112112
iso-week-year full-table-name)])))
113113

114+
;; This var is used in testing to simulate migration 74 being applied without
115+
;; adding the idx_reports_id index to partitions. Changing this behavior in
116+
;; migration 74 should be safe because the index creation is guarded by
117+
;; 'if not exists' in both the changed migration 74 and in the newer 76.
118+
(def ^:dynamic add-report-id-idx? true)
119+
114120
(defn create-reports-partition
115121
"Creates a partition in the reports table"
116122
[date]
@@ -131,35 +137,38 @@
131137
" FOREIGN KEY (status_id) REFERENCES report_statuses(id) ON DELETE CASCADE")
132138
iso-week-year)])
133139
(fn [full-table-name iso-week-year]
134-
[(format "CREATE UNIQUE INDEX IF NOT EXISTS idx_reports_id_%s ON %s USING btree (id)"
135-
iso-week-year full-table-name)
136-
(format "CREATE INDEX IF NOT EXISTS idx_reports_compound_id_%s ON %s USING btree (producer_timestamp, certname, hash) WHERE (start_time IS NOT NULL)"
137-
iso-week-year full-table-name)
138-
(format "CREATE INDEX IF NOT EXISTS idx_reports_noop_pending_%s ON %s USING btree (noop_pending) WHERE (noop_pending = true)"
139-
iso-week-year full-table-name)
140-
(format "CREATE INDEX IF NOT EXISTS idx_reports_prod_%s ON %s USING btree (producer_id)"
141-
iso-week-year full-table-name)
142-
(format "CREATE INDEX IF NOT EXISTS idx_reports_producer_timestamp_%s ON %s USING btree (producer_timestamp)"
143-
iso-week-year full-table-name)
144-
(format "CREATE INDEX IF NOT EXISTS idx_reports_producer_timestamp_by_hour_certname_%s ON %s USING btree (date_trunc('hour'::text, timezone('UTC'::text, producer_timestamp)), producer_timestamp, certname)"
145-
iso-week-year full-table-name)
146-
(format "CREATE INDEX IF NOT EXISTS reports_cached_catalog_status_on_fail_%s ON %s USING btree (cached_catalog_status) WHERE (cached_catalog_status = 'on_failure'::text)"
147-
iso-week-year full-table-name)
148-
(format "CREATE INDEX IF NOT EXISTS reports_catalog_uuid_idx_%s ON %s USING btree (catalog_uuid)"
149-
iso-week-year full-table-name)
150-
(format "CREATE INDEX IF NOT EXISTS reports_certname_idx_%s ON %s USING btree (certname)"
151-
iso-week-year full-table-name)
152-
(format "CREATE INDEX IF NOT EXISTS reports_end_time_idx_%s ON %s USING btree (end_time)"
153-
iso-week-year full-table-name)
154-
(format "CREATE INDEX IF NOT EXISTS reports_environment_id_idx_%s ON %s USING btree (environment_id)"
155-
iso-week-year full-table-name)
156-
(format "CREATE UNIQUE INDEX IF NOT EXISTS reports_hash_expr_idx_%s ON %s USING btree (encode(hash, 'hex'::text))"
157-
iso-week-year full-table-name)
158-
(format "CREATE INDEX IF NOT EXISTS reports_job_id_idx_%s ON %s USING btree (job_id) WHERE (job_id IS NOT NULL)"
159-
iso-week-year full-table-name)
160-
(format "CREATE INDEX IF NOT EXISTS reports_noop_idx_%s ON %s USING btree (noop) WHERE (noop = true)"
161-
iso-week-year full-table-name)
162-
(format "CREATE INDEX IF NOT EXISTS reports_status_id_idx_%s ON %s USING btree (status_id)"
163-
iso-week-year full-table-name)
164-
(format "CREATE INDEX IF NOT EXISTS reports_tx_uuid_expr_idx_%s ON %s USING btree (((transaction_uuid)::text))"
165-
iso-week-year full-table-name)])))
140+
(let [indexes
141+
[(format "CREATE INDEX IF NOT EXISTS idx_reports_compound_id_%s ON %s USING btree (producer_timestamp, certname, hash) WHERE (start_time IS NOT NULL)"
142+
iso-week-year full-table-name)
143+
(format "CREATE INDEX IF NOT EXISTS idx_reports_noop_pending_%s ON %s USING btree (noop_pending) WHERE (noop_pending = true)"
144+
iso-week-year full-table-name)
145+
(format "CREATE INDEX IF NOT EXISTS idx_reports_prod_%s ON %s USING btree (producer_id)"
146+
iso-week-year full-table-name)
147+
(format "CREATE INDEX IF NOT EXISTS idx_reports_producer_timestamp_%s ON %s USING btree (producer_timestamp)"
148+
iso-week-year full-table-name)
149+
(format "CREATE INDEX IF NOT EXISTS idx_reports_producer_timestamp_by_hour_certname_%s ON %s USING btree (date_trunc('hour'::text, timezone('UTC'::text, producer_timestamp)), producer_timestamp, certname)"
150+
iso-week-year full-table-name)
151+
(format "CREATE INDEX IF NOT EXISTS reports_cached_catalog_status_on_fail_%s ON %s USING btree (cached_catalog_status) WHERE (cached_catalog_status = 'on_failure'::text)"
152+
iso-week-year full-table-name)
153+
(format "CREATE INDEX IF NOT EXISTS reports_catalog_uuid_idx_%s ON %s USING btree (catalog_uuid)"
154+
iso-week-year full-table-name)
155+
(format "CREATE INDEX IF NOT EXISTS reports_certname_idx_%s ON %s USING btree (certname)"
156+
iso-week-year full-table-name)
157+
(format "CREATE INDEX IF NOT EXISTS reports_end_time_idx_%s ON %s USING btree (end_time)"
158+
iso-week-year full-table-name)
159+
(format "CREATE INDEX IF NOT EXISTS reports_environment_id_idx_%s ON %s USING btree (environment_id)"
160+
iso-week-year full-table-name)
161+
(format "CREATE UNIQUE INDEX IF NOT EXISTS reports_hash_expr_idx_%s ON %s USING btree (encode(hash, 'hex'::text))"
162+
iso-week-year full-table-name)
163+
(format "CREATE INDEX IF NOT EXISTS reports_job_id_idx_%s ON %s USING btree (job_id) WHERE (job_id IS NOT NULL)"
164+
iso-week-year full-table-name)
165+
(format "CREATE INDEX IF NOT EXISTS reports_noop_idx_%s ON %s USING btree (noop) WHERE (noop = true)"
166+
iso-week-year full-table-name)
167+
(format "CREATE INDEX IF NOT EXISTS reports_status_id_idx_%s ON %s USING btree (status_id)"
168+
iso-week-year full-table-name)
169+
(format "CREATE INDEX IF NOT EXISTS reports_tx_uuid_expr_idx_%s ON %s USING btree (((transaction_uuid)::text))"
170+
iso-week-year full-table-name)]]
171+
(if add-report-id-idx?
172+
(conj indexes (format "CREATE UNIQUE INDEX IF NOT EXISTS idx_reports_id_%s ON %s USING btree (id)"
173+
iso-week-year full-table-name))
174+
indexes)))))

test/puppetlabs/puppetdb/scf/migrate_test.clj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
[puppetlabs.puppetdb.testutils.db :refer [*db* with-test-db]]
2121
[puppetlabs.puppetdb.scf.hash :as shash]
2222
[puppetlabs.puppetdb.time :refer [ago days now to-timestamp]]
23+
[puppetlabs.puppetdb.scf.partitioning :as part]
2324
[clojure.string :as str])
2425
(:import (java.time ZoneId ZonedDateTime)
2526
(java.sql Timestamp)))
@@ -1474,3 +1475,24 @@
14741475
(apply-migration-for-testing! 76)
14751476
;; migration 76 should be a no-op
14761477
(check-idx-reports-id)))))
1478+
1479+
(deftest migration-76-adds-report-id-idx-when-not-added-by-migration-74
1480+
(testing "All report paritions have idx_reports_id index when old version of 74 applied"
1481+
(jdbc/with-db-connection *db*
1482+
(clear-db-for-testing!)
1483+
;; don't add the idx_reports_id index when fast forwarding past migration 74
1484+
(binding [part/add-report-id-idx? false]
1485+
(fast-forward-to-migration! 75))
1486+
(let [assert-no-index (fn [index indexes]
1487+
(is (nil? (some #(str/includes? % index) indexes))))]
1488+
;; check that idx_reports_id wasn't added by migration 74
1489+
(dorun (->> (utils/partition-names "reports")
1490+
(map utils/table-indexes)
1491+
(map (partial assert-no-index "idx_reports_id")))))
1492+
(apply-migration-for-testing! 76)
1493+
(let [assert-index-exists (fn [index indexes]
1494+
(is (some #(str/includes? % index) indexes)))]
1495+
;; check that idx_reports_id is now present in all paritions
1496+
(dorun (->> (utils/partition-names "reports")
1497+
(map utils/table-indexes)
1498+
(map (partial assert-index-exists "idx_reports_id"))))))))

0 commit comments

Comments
 (0)