github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/migration/migrate_config_pinned_versions_test.go (about)

     1  package migration_test
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  
     7  	. "github.com/onsi/ginkgo"
     8  	. "github.com/onsi/gomega"
     9  )
    10  
    11  var _ = Describe("Migrate config pinned resources", func() {
    12  	const preMigrationVersion = 1588860260
    13  	const postMigrationVersion = 1589991895
    14  
    15  	var (
    16  		db *sql.DB
    17  	)
    18  
    19  	Context("Up", func() {
    20  		It("migrates all the resources that are pinned through it's resource config into the resource pins table", func() {
    21  			db = postgresRunner.OpenDBAtVersion(preMigrationVersion)
    22  
    23  			_, err := db.Exec(`
    24  			INSERT INTO teams(id, name) VALUES
    25  			(1, 'some-team')
    26  			`)
    27  			Expect(err).NotTo(HaveOccurred())
    28  
    29  			_, err = db.Exec(`
    30  			INSERT INTO pipelines(id, team_id, name) VALUES
    31  			(1, 1, 'pipeline1'),
    32  			(2, 1, 'pipeline2')
    33  			`)
    34  			Expect(err).NotTo(HaveOccurred())
    35  
    36  			var resource1ID, resource2ID, resource3ID, resource4ID int
    37  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-1', 1, '{"type": "some-type"}', true, 'some-type') RETURNING id`).Scan(&resource1ID)
    38  			Expect(err).NotTo(HaveOccurred())
    39  
    40  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-2', 1, '{"type": "some-type", "version": {"ref": "v1"}}', true, 'some-type') RETURNING id`).Scan(&resource2ID)
    41  			Expect(err).NotTo(HaveOccurred())
    42  
    43  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-3', 2, '{"type": "some-type"}', true, 'some-type') RETURNING id`).Scan(&resource3ID)
    44  			Expect(err).NotTo(HaveOccurred())
    45  
    46  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-1', 2, '{"type": "some-type", "version": {"ref": "v2"}}', true, 'some-type') RETURNING id`).Scan(&resource4ID)
    47  			Expect(err).NotTo(HaveOccurred())
    48  
    49  			_, err = db.Exec(`INSERT INTO resource_pins(resource_id, version, comment_text) VALUES($1, '{"ref": "v0"}', 'api-pinned')`, resource1ID)
    50  			Expect(err).NotTo(HaveOccurred())
    51  
    52  			_, err = db.Exec(`INSERT INTO resource_pins(resource_id, version, comment_text) VALUES($1, '{"ref": "api"}', 'api-pinned')`, resource2ID)
    53  			Expect(err).NotTo(HaveOccurred())
    54  
    55  			db.Close()
    56  
    57  			db = postgresRunner.OpenDBAtVersion(postMigrationVersion)
    58  
    59  			type pinnedResource struct {
    60  				resourceID int
    61  				version    map[string]string
    62  				config     bool
    63  				comment    string
    64  			}
    65  
    66  			rows, err := db.Query(`SELECT resource_id, version, config, comment_text FROM resource_pins`)
    67  			Expect(err).NotTo(HaveOccurred())
    68  
    69  			var pinnedResources []pinnedResource
    70  			for rows.Next() {
    71  				var p pinnedResource
    72  				var version []byte
    73  				var pinComment sql.NullString
    74  
    75  				err := rows.Scan(&p.resourceID, &version, &p.config, &pinComment)
    76  				Expect(err).NotTo(HaveOccurred())
    77  
    78  				err = json.Unmarshal(version, &p.version)
    79  				Expect(err).NotTo(HaveOccurred())
    80  
    81  				if pinComment.Valid {
    82  					p.comment = pinComment.String
    83  				}
    84  
    85  				pinnedResources = append(pinnedResources, p)
    86  			}
    87  
    88  			expectedPinnedResources := []pinnedResource{
    89  				{
    90  					resourceID: resource1ID,
    91  					version:    map[string]string{"ref": "v0"},
    92  					config:     false,
    93  					comment:    "api-pinned",
    94  				},
    95  				{
    96  					resourceID: resource2ID,
    97  					version:    map[string]string{"ref": "v1"},
    98  					config:     true,
    99  				},
   100  				{
   101  					resourceID: resource4ID,
   102  					version:    map[string]string{"ref": "v2"},
   103  					config:     true,
   104  				},
   105  			}
   106  
   107  			_ = db.Close()
   108  
   109  			Expect(pinnedResources).To(HaveLen(3))
   110  			Expect(pinnedResources).To(ConsistOf(expectedPinnedResources))
   111  		})
   112  	})
   113  
   114  	Context("Down", func() {
   115  		It("removes the config pinned resources", func() {
   116  			db = postgresRunner.OpenDBAtVersion(postMigrationVersion)
   117  
   118  			_, err := db.Exec(`
   119  			INSERT INTO teams(id, name) VALUES
   120  			(1, 'some-team')
   121  			`)
   122  			Expect(err).NotTo(HaveOccurred())
   123  
   124  			_, err = db.Exec(`
   125  			INSERT INTO pipelines(id, team_id, name) VALUES
   126  			(1, 1, 'pipeline1'),
   127  			(2, 1, 'pipeline2')
   128  			`)
   129  			Expect(err).NotTo(HaveOccurred())
   130  
   131  			var resource1ID, resource2ID, resource3ID, resource4ID int
   132  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-1', 1, '{"type": "some-type"}', true, 'some-type') RETURNING id`).Scan(&resource1ID)
   133  			Expect(err).NotTo(HaveOccurred())
   134  
   135  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-2', 1, '{"type": "some-type", "version": {"ref": "v1"}}', true, 'some-type') RETURNING id`).Scan(&resource2ID)
   136  			Expect(err).NotTo(HaveOccurred())
   137  
   138  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-3', 2, '{"type": "some-type"}', true, 'some-type') RETURNING id`).Scan(&resource3ID)
   139  			Expect(err).NotTo(HaveOccurred())
   140  
   141  			err = db.QueryRow(`INSERT INTO resources(name, pipeline_id, config, active, type) VALUES('resource-1', 2, '{"type": "some-type", "version": {"ref": "v2"}}', true, 'some-type') RETURNING id`).Scan(&resource4ID)
   142  			Expect(err).NotTo(HaveOccurred())
   143  
   144  			_, err = db.Exec(`INSERT INTO resource_pins(resource_id, version, config, comment_text) VALUES($1, '{"ref": "v0"}', false, '')`, resource1ID)
   145  			Expect(err).NotTo(HaveOccurred())
   146  
   147  			_, err = db.Exec(`INSERT INTO resource_pins(resource_id, version, config, comment_text) VALUES($1, '{"ref": "v1"}', true, '')`, resource2ID)
   148  			Expect(err).NotTo(HaveOccurred())
   149  
   150  			_, err = db.Exec(`INSERT INTO resource_pins(resource_id, version, config, comment_text) VALUES($1, '{"ref": "v2"}', true, '')`, resource4ID)
   151  			Expect(err).NotTo(HaveOccurred())
   152  
   153  			db.Close()
   154  
   155  			db = postgresRunner.OpenDBAtVersion(preMigrationVersion)
   156  
   157  			rows, err := db.Query(`SELECT resource_id, version FROM resource_pins`)
   158  			Expect(err).NotTo(HaveOccurred())
   159  
   160  			type pinnedResource struct {
   161  				resourceID int
   162  				version    map[string]string
   163  			}
   164  
   165  			var pinnedResources []pinnedResource
   166  			for rows.Next() {
   167  				var p pinnedResource
   168  				var version []byte
   169  
   170  				err := rows.Scan(&p.resourceID, &version)
   171  				Expect(err).NotTo(HaveOccurred())
   172  
   173  				err = json.Unmarshal(version, &p.version)
   174  				Expect(err).NotTo(HaveOccurred())
   175  
   176  				pinnedResources = append(pinnedResources, p)
   177  			}
   178  
   179  			expectedPinnedResources := []pinnedResource{
   180  				{
   181  					resourceID: resource1ID,
   182  					version:    map[string]string{"ref": "v0"},
   183  				},
   184  			}
   185  
   186  			_ = db.Close()
   187  
   188  			Expect(pinnedResources).To(HaveLen(1))
   189  			Expect(pinnedResources).To(ConsistOf(expectedPinnedResources))
   190  		})
   191  	})
   192  })