github.com/release-engineering/exodus-rsync@v1.11.2/internal/cmd/cmd_gw_errors_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/golang/mock/gomock"
     8  	"github.com/release-engineering/exodus-rsync/internal/gw"
     9  	"github.com/release-engineering/exodus-rsync/internal/walk"
    10  )
    11  
    12  type mockClientConfigurator func(*gomock.Controller, *gw.MockClient)
    13  
    14  func setupFailedUpload(ctrl *gomock.Controller, client *gw.MockClient) {
    15  	// Creating a publish succeeds
    16  	publish := gw.NewMockPublish(ctrl)
    17  	client.EXPECT().NewPublish(gomock.Any()).Return(publish, nil)
    18  
    19  	publish.EXPECT().ID().Return("3e0a4539-be4a-437e-a45f-6d72f7192f17").AnyTimes()
    20  
    21  	client.EXPECT().EnsureUploaded(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
    22  		Return(fmt.Errorf("simulated error"))
    23  }
    24  
    25  func setupFailedNewPublish(_ *gomock.Controller, client *gw.MockClient) {
    26  	client.EXPECT().NewPublish(gomock.Any()).Return(nil, fmt.Errorf("simulated error"))
    27  }
    28  
    29  func setupFailedAddItems(ctrl *gomock.Controller, client *gw.MockClient) {
    30  	// EnsureUploaded succeeds, and (importantly) must add some items
    31  	client.EXPECT().EnsureUploaded(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
    32  		Do(func(_ interface{}, _ interface{}, onUploaded func(walk.SyncItem) error, onPresent func(walk.SyncItem) error, onDuplicate func(walk.SyncItem) error) {
    33  			// Simulate that a couple of items were uploaded.
    34  			onUploaded(walk.SyncItem{SrcPath: "file1", Key: "abc123"})
    35  			onUploaded(walk.SyncItem{SrcPath: "file2", Key: "aabbcc"})
    36  			onDuplicate(walk.SyncItem{SrcPath: "file3", Key: "abc123"})
    37  			onPresent(walk.SyncItem{SrcPath: "file4", Key: "a1b2c3"})
    38  		}).
    39  		Return(nil)
    40  
    41  	// Creating a publish succeeds
    42  	publish := gw.NewMockPublish(ctrl)
    43  	client.EXPECT().NewPublish(gomock.Any()).Return(publish, nil)
    44  
    45  	publish.EXPECT().ID().Return("3e0a4539-be4a-437e-a45f-6d72f7192f17").AnyTimes()
    46  
    47  	// Publish can't have items added
    48  	publish.EXPECT().AddItems(gomock.Any(), gomock.Any()).Return(fmt.Errorf("simulated error"))
    49  }
    50  
    51  func setupFailedCommit(ctrl *gomock.Controller, client *gw.MockClient) {
    52  	// EnsureUploaded succeeds, and (importantly) must add some items
    53  	client.EXPECT().EnsureUploaded(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
    54  		Do(func(_ interface{}, _ interface{}, onUploaded func(walk.SyncItem) error, _ interface{}, _ interface{}) {
    55  			// Simulate that a couple of items were uploaded.
    56  			onUploaded(walk.SyncItem{SrcPath: "file1", Key: "abc123"})
    57  			onUploaded(walk.SyncItem{SrcPath: "file2", Key: "aabbcc"})
    58  		}).
    59  		Return(nil)
    60  
    61  	// Creating a publish succeeds
    62  	publish := gw.NewMockPublish(ctrl)
    63  	client.EXPECT().NewPublish(gomock.Any()).Return(publish, nil)
    64  
    65  	publish.EXPECT().ID().Return("3e0a4539-be4a-437e-a45f-6d72f7192f17").AnyTimes()
    66  
    67  	// Adding items succeeds
    68  	publish.EXPECT().AddItems(gomock.Any(), gomock.Any()).Return(nil)
    69  
    70  	// Committing fails
    71  	publish.EXPECT().Commit(gomock.Any(), gomock.Any()).Return(fmt.Errorf("simulated error"))
    72  }
    73  
    74  func setupFailedJoinPublish(ctrl *gomock.Controller, client *gw.MockClient) {
    75  	publish := gw.NewMockPublish(ctrl)
    76  
    77  	client.EXPECT().GetPublish(gomock.Any(), gomock.Any()).Return(publish, fmt.Errorf("simulated error"))
    78  }
    79  
    80  func TestMainUploadFailed(t *testing.T) {
    81  	tests := []struct {
    82  		message   string
    83  		setupMock mockClientConfigurator
    84  		exitCode  int
    85  	}{
    86  		{"can't upload files", setupFailedUpload, 25},
    87  		{"can't create publish", setupFailedNewPublish, 62},
    88  		{"can't add items to publish", setupFailedAddItems, 51},
    89  		{"can't commit publish", setupFailedCommit, 71},
    90  	}
    91  	for _, tt := range tests {
    92  		t.Run(tt.message, func(t *testing.T) {
    93  
    94  			logs := CaptureLogger(t)
    95  			ctrl := MockController(t)
    96  
    97  			mockGw := gw.NewMockInterface(ctrl)
    98  			ext.gw = mockGw
    99  
   100  			mockClient := gw.NewMockClient(ctrl)
   101  
   102  			SetConfig(t, `
   103  gwcert: $HOME/certs/$USER.crt
   104  gwkey: $HOME/certs/$USER.key
   105  gwurl: https://exodus-gw.example.com/
   106  
   107  environments:
   108  - prefix: some-dest
   109    gwenv: test
   110  `)
   111  
   112  			mockGw.EXPECT().NewClient(gomock.Any(), gomock.Any()).Return(mockClient, nil)
   113  
   114  			tt.setupMock(ctrl, mockClient)
   115  
   116  			exitCode := Main([]string{
   117  				"exodus-rsync", ".", "some-dest:/foo/bar",
   118  			})
   119  
   120  			// It should exit with error.
   121  			if exitCode != tt.exitCode {
   122  				t.Error("returned incorrect exit code", exitCode)
   123  			}
   124  
   125  			entry := FindEntry(logs, tt.message)
   126  			if entry == nil {
   127  				t.Fatal("missing expected log message")
   128  			}
   129  
   130  			if fmt.Sprint(entry.Fields["error"]) != "simulated error" {
   131  				t.Errorf("unexpected error %v", entry.Fields["error"])
   132  			}
   133  		})
   134  	}
   135  }
   136  
   137  func TestMainJoinPublishFailed(t *testing.T) {
   138  	test := struct {
   139  		message   string
   140  		setupMock mockClientConfigurator
   141  		exitCode  int
   142  	}{"can't join publish", setupFailedJoinPublish, 67}
   143  
   144  	t.Run(test.message, func(t *testing.T) {
   145  
   146  		logs := CaptureLogger(t)
   147  		ctrl := MockController(t)
   148  
   149  		mockGw := gw.NewMockInterface(ctrl)
   150  		ext.gw = mockGw
   151  
   152  		mockClient := gw.NewMockClient(ctrl)
   153  
   154  		SetConfig(t, `
   155  gwcert: $HOME/certs/$USER.crt
   156  gwkey: $HOME/certs/$USER.key
   157  gwurl: https://exodus-gw.example.com/
   158  environments:
   159  - prefix: some-dest
   160    gwenv: test
   161  `)
   162  
   163  		mockGw.EXPECT().NewClient(gomock.Any(), gomock.Any()).Return(mockClient, nil)
   164  
   165  		test.setupMock(ctrl, mockClient)
   166  
   167  		exitCode := Main([]string{
   168  			"exodus-rsync", ".", "some-dest:/foo/bar", "--exodus-publish", "3e0a4539-be4a-437e-a45f-6d72f7192f17",
   169  		})
   170  
   171  		// It should exit with error.
   172  		if exitCode != test.exitCode {
   173  			t.Error("returned incorrect exit code", exitCode)
   174  		}
   175  
   176  		entry := FindEntry(logs, test.message)
   177  		if entry == nil {
   178  			t.Fatal("missing expected log message")
   179  		}
   180  
   181  		if fmt.Sprint(entry.Fields["error"]) != "simulated error" {
   182  			t.Errorf("unexpected error %v", entry.Fields["error"])
   183  		}
   184  	})
   185  }