get.porter.sh/porter@v1.3.0/pkg/storage/plugins/testplugin/plugin.go (about) 1 package testplugin 2 3 import ( 4 "context" 5 "fmt" 6 7 "get.porter.sh/porter/pkg/portercontext" 8 "get.porter.sh/porter/pkg/storage/plugins" 9 "get.porter.sh/porter/pkg/storage/plugins/mongodb" 10 "get.porter.sh/porter/pkg/storage/plugins/mongodb_docker" 11 "get.porter.sh/porter/tests" 12 "github.com/hashicorp/go-multierror" 13 "go.mongodb.org/mongo-driver/bson" 14 ) 15 16 var ( 17 _ plugins.StorageProtocol = &TestStoragePlugin{} 18 ) 19 20 // TestStoragePlugin is a test helper that implements a storage plugin backed by a 21 // mongodb instance that saves data to a temporary directory. 22 type TestStoragePlugin struct { 23 store *mongodb.Store 24 tc *portercontext.TestContext 25 database string 26 } 27 28 func NewTestStoragePlugin(tc *portercontext.TestContext) *TestStoragePlugin { 29 return &TestStoragePlugin{tc: tc} 30 } 31 32 // Connect creates a new database for the current test 33 // The plugin itself is responsible for ensuring it was called. 34 // Close is called automatically when the plugin is used by Porter. 35 func (s *TestStoragePlugin) Connect(ctx context.Context) error { 36 if s.store != nil { 37 return nil 38 } 39 40 s.database = tests.GenerateDatabaseName(s.tc.T.Name()) 41 42 // Try to connect to a dev instance of mongo, otherwise run a one off mongo instance 43 err := s.useDevDatabase(ctx) 44 if err != nil { 45 // Didn't find a dev mongo instance, so let's run one just for this test 46 return s.runTestDatabase(ctx) 47 } 48 49 return s.store.RemoveDatabase(ctx) // Start with a fresh test database 50 } 51 52 func (s *TestStoragePlugin) useDevDatabase(ctx context.Context) error { 53 cfg := mongodb.PluginConfig{ 54 URL: fmt.Sprintf("mongodb://localhost:27017/%s?connect=direct", s.database), 55 Timeout: 10, 56 } 57 devMongo := mongodb.NewStore(s.tc.Context, cfg) 58 err := devMongo.Connect(ctx) 59 if err != nil { 60 return err 61 } 62 63 err = devMongo.Ping(ctx) 64 if err != nil { 65 return err 66 } 67 68 s.store = devMongo 69 return nil 70 } 71 72 func (s *TestStoragePlugin) runTestDatabase(ctx context.Context) error { 73 testMongo, err := mongodb_docker.EnsureMongoIsRunning(ctx, s.tc.Context, "porter-test-mongodb-plugin", "27017", "", s.database, 10) 74 if err != nil { 75 return err 76 } 77 s.store = testMongo 78 return nil 79 } 80 81 // Close removes the test database and closes the connection. 82 func (s *TestStoragePlugin) Close() error { 83 if s.store != nil { 84 var bigErr *multierror.Error 85 bigErr = multierror.Append(bigErr, s.store.RemoveDatabase(context.Background())) 86 bigErr = multierror.Append(bigErr, s.store.Close()) 87 s.store = nil 88 return bigErr.ErrorOrNil() 89 } 90 return nil 91 } 92 93 func (s *TestStoragePlugin) EnsureIndex(ctx context.Context, opts plugins.EnsureIndexOptions) error { 94 if err := s.Connect(ctx); err != nil { 95 return err 96 } 97 return s.store.EnsureIndex(ctx, opts) 98 } 99 100 func (s *TestStoragePlugin) Aggregate(ctx context.Context, opts plugins.AggregateOptions) ([]bson.Raw, error) { 101 if err := s.Connect(ctx); err != nil { 102 return nil, err 103 } 104 return s.store.Aggregate(ctx, opts) 105 } 106 107 func (s *TestStoragePlugin) Count(ctx context.Context, opts plugins.CountOptions) (int64, error) { 108 if err := s.Connect(ctx); err != nil { 109 return 0, err 110 } 111 return s.store.Count(ctx, opts) 112 } 113 114 func (s *TestStoragePlugin) Find(ctx context.Context, opts plugins.FindOptions) ([]bson.Raw, error) { 115 if err := s.Connect(ctx); err != nil { 116 return nil, err 117 } 118 return s.store.Find(ctx, opts) 119 } 120 121 func (s *TestStoragePlugin) Insert(ctx context.Context, opts plugins.InsertOptions) error { 122 if err := s.Connect(ctx); err != nil { 123 return err 124 } 125 return s.store.Insert(ctx, opts) 126 } 127 128 func (s *TestStoragePlugin) Patch(ctx context.Context, opts plugins.PatchOptions) error { 129 if err := s.Connect(ctx); err != nil { 130 return err 131 } 132 return s.store.Patch(ctx, opts) 133 } 134 135 func (s *TestStoragePlugin) Remove(ctx context.Context, opts plugins.RemoveOptions) error { 136 if err := s.Connect(ctx); err != nil { 137 return err 138 } 139 return s.store.Remove(ctx, opts) 140 } 141 142 func (s *TestStoragePlugin) Update(ctx context.Context, opts plugins.UpdateOptions) error { 143 if err := s.Connect(ctx); err != nil { 144 return err 145 } 146 return s.store.Update(ctx, opts) 147 }