github.com/bartle-stripe/trillian@v1.2.1/storage/testonly/transaction.go (about)

     1  // Copyright 2018 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package testonly
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"time"
    21  
    22  	"github.com/google/trillian"
    23  	"github.com/google/trillian/storage"
    24  	"google.golang.org/grpc/codes"
    25  	"google.golang.org/grpc/status"
    26  )
    27  
    28  // RunOnLogTX is a helper for mocking out the LogStorage.ReadWriteTransaction method.
    29  func RunOnLogTX(tx storage.LogTreeTX) func(ctx context.Context, treeID int64, f storage.LogTXFunc) error {
    30  	return func(ctx context.Context, _ int64, f storage.LogTXFunc) error {
    31  		defer tx.Close()
    32  		if err := f(ctx, tx); err != nil {
    33  			return err
    34  		}
    35  		return tx.Commit()
    36  	}
    37  }
    38  
    39  // RunOnMapTX is a helper for mocking out the MapStorage.ReadWriteTransaction method.
    40  func RunOnMapTX(tx storage.MapTreeTX) func(ctx context.Context, treeID int64, f storage.MapTXFunc) error {
    41  	return func(ctx context.Context, _ int64, f storage.MapTXFunc) error {
    42  		defer tx.Close()
    43  		if err := f(ctx, tx); err != nil {
    44  			return err
    45  		}
    46  		return tx.Commit()
    47  	}
    48  }
    49  
    50  // RunOnAdminTX is a helper for mocking out the AdminStorage.ReadWriteTransaction method.
    51  func RunOnAdminTX(tx storage.AdminTX) func(ctx context.Context, f storage.AdminTXFunc) error {
    52  	return func(ctx context.Context, f storage.AdminTXFunc) error {
    53  		defer tx.Close()
    54  		if err := f(ctx, tx); err != nil {
    55  			return err
    56  		}
    57  		return tx.Commit()
    58  	}
    59  }
    60  
    61  // ErrNotImplemented is returned by unimplemented methods on the storage fakes.
    62  var ErrNotImplemented = errors.New("not implemented")
    63  
    64  // FakeLogStorage is a LogStorage implementation which is used for testing.
    65  type FakeLogStorage struct {
    66  	TX         storage.LogTreeTX
    67  	ReadOnlyTX storage.ReadOnlyLogTreeTX
    68  
    69  	TXErr                 error
    70  	QueueLeavesErr        error
    71  	AddSequencedLeavesErr error
    72  }
    73  
    74  // Snapshot implements LogStorage.Snapshot
    75  func (f *FakeLogStorage) Snapshot(ctx context.Context) (storage.ReadOnlyLogTX, error) {
    76  	return nil, ErrNotImplemented
    77  }
    78  
    79  // SnapshotForTree implements LogStorage.SnapshotForTree
    80  func (f *FakeLogStorage) SnapshotForTree(ctx context.Context, _ *trillian.Tree) (storage.ReadOnlyLogTreeTX, error) {
    81  	return f.ReadOnlyTX, f.TXErr
    82  }
    83  
    84  // ReadWriteTransaction implements LogStorage.ReadWriteTransaction
    85  func (f *FakeLogStorage) ReadWriteTransaction(ctx context.Context, tree *trillian.Tree, fn storage.LogTXFunc) error {
    86  	if f.TXErr != nil {
    87  		return f.TXErr
    88  	}
    89  	return RunOnLogTX(f.TX)(ctx, tree.TreeId, fn)
    90  }
    91  
    92  // QueueLeaves implements LogStorage.QueueLeaves.
    93  func (f *FakeLogStorage) QueueLeaves(ctx context.Context, tree *trillian.Tree, leaves []*trillian.LogLeaf, queueTimestamp time.Time) ([]*trillian.QueuedLogLeaf, error) {
    94  	if f.QueueLeavesErr != nil {
    95  		return nil, f.QueueLeavesErr
    96  	}
    97  	return make([]*trillian.QueuedLogLeaf, len(leaves)), nil
    98  }
    99  
   100  // AddSequencedLeaves implements LogStorage.AddSequencedLeaves.
   101  func (f *FakeLogStorage) AddSequencedLeaves(ctx context.Context, tree *trillian.Tree, leaves []*trillian.LogLeaf, timestamp time.Time) ([]*trillian.QueuedLogLeaf, error) {
   102  	if f.AddSequencedLeavesErr != nil {
   103  		return nil, f.AddSequencedLeavesErr
   104  	}
   105  	res := make([]*trillian.QueuedLogLeaf, len(leaves))
   106  	for i := range res {
   107  		res[i] = &trillian.QueuedLogLeaf{Status: status.New(codes.OK, "OK").Proto()}
   108  	}
   109  	return res, nil
   110  }
   111  
   112  // CheckDatabaseAccessible implements LogStorage.CheckDatabaseAccessible
   113  func (f *FakeLogStorage) CheckDatabaseAccessible(ctx context.Context) error {
   114  	return nil
   115  }
   116  
   117  // FakeMapStorage is a MapStorage implementation which is used for testing.
   118  type FakeMapStorage struct {
   119  	TX          storage.MapTreeTX
   120  	ReadOnlyTX  storage.ReadOnlyMapTreeTX
   121  	SnapshotErr error
   122  }
   123  
   124  // Snapshot implements MapStorage.Snapshot
   125  func (f *FakeMapStorage) Snapshot(ctx context.Context) (storage.ReadOnlyMapTX, error) {
   126  	return nil, ErrNotImplemented
   127  }
   128  
   129  // SnapshotForTree implements MapStorage.SnapshotForTree
   130  func (f *FakeMapStorage) SnapshotForTree(ctx context.Context, _ *trillian.Tree) (storage.ReadOnlyMapTreeTX, error) {
   131  	return f.ReadOnlyTX, f.SnapshotErr
   132  }
   133  
   134  // ReadWriteTransaction implements MapStorage.ReadWriteTransaction
   135  func (f *FakeMapStorage) ReadWriteTransaction(ctx context.Context, tree *trillian.Tree, fn storage.MapTXFunc) error {
   136  	return RunOnMapTX(f.TX)(ctx, tree.TreeId, fn)
   137  }
   138  
   139  // CheckDatabaseAccessible implements MapStorage.CheckDatabaseAccessible
   140  func (f *FakeMapStorage) CheckDatabaseAccessible(ctx context.Context) error {
   141  	return nil
   142  }
   143  
   144  // FakeAdminStorage is a AdminStorage implementation which is used for testing.
   145  type FakeAdminStorage struct {
   146  	TX          []storage.AdminTX
   147  	ReadOnlyTX  []storage.ReadOnlyAdminTX
   148  	TXErr       []error
   149  	SnapshotErr []error
   150  }
   151  
   152  // Begin implements AdminStorage.Begin
   153  func (f *FakeAdminStorage) Begin(ctx context.Context) (storage.AdminTX, error) {
   154  	return nil, ErrNotImplemented
   155  }
   156  
   157  // Snapshot implements AdminStorage.Snapshot
   158  func (f *FakeAdminStorage) Snapshot(ctx context.Context) (storage.ReadOnlyAdminTX, error) {
   159  	if len(f.SnapshotErr) > 0 {
   160  		e := f.SnapshotErr[0]
   161  		f.SnapshotErr = f.SnapshotErr[1:]
   162  		return nil, e
   163  	}
   164  	r := f.ReadOnlyTX[0]
   165  	f.ReadOnlyTX = f.ReadOnlyTX[1:]
   166  	return r, nil
   167  }
   168  
   169  // ReadWriteTransaction implements AdminStorage.ReadWriteTransaction
   170  func (f *FakeAdminStorage) ReadWriteTransaction(ctx context.Context, fn storage.AdminTXFunc) error {
   171  	if len(f.TXErr) > 0 {
   172  		e := f.TXErr[0]
   173  		f.TXErr = f.TXErr[1:]
   174  		return e
   175  	}
   176  	t := f.TX[0]
   177  	f.TX = f.TX[1:]
   178  	return RunOnAdminTX(t)(ctx, fn)
   179  }
   180  
   181  // CheckDatabaseAccessible implements AdminStorage.CheckDatabaseAccessible
   182  func (f *FakeAdminStorage) CheckDatabaseAccessible(ctx context.Context) error {
   183  	return nil
   184  }