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  }