github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/steampipeconfig/connection_test.go (about)

     1  package steampipeconfig
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/otiai10/copy"
    12  	"github.com/turbot/steampipe/pkg/constants"
    13  	"github.com/turbot/steampipe/pkg/filepaths"
    14  	"github.com/turbot/steampipe/pkg/utils"
    15  )
    16  
    17  type getConnectionsToUpdateTest struct {
    18  	// hcl connection config(s)
    19  	required []string
    20  	// current connection state
    21  	current  ConnectionStateMap
    22  	expected interface{}
    23  }
    24  
    25  var connectionTest1ModTime = getTestFileModTime("test_data/connections_to_update/plugins_src/hub.steampipe.io/plugins/turbot/connection-test-1@latest/connection-test-1.plugin")
    26  var connectionTest2ModTime = getTestFileModTime("test_data/connections_to_update/plugins_src/hub.steampipe.io/plugins/turbot/connection-test-2@latest/connection-test-2.plugin")
    27  
    28  var testCasesGetConnectionsToUpdate = map[string]getConnectionsToUpdateTest{
    29  	"no changes": {
    30  		required: []string{
    31  			`connection "a" {
    32    plugin = "connection-test-1"
    33  }
    34  `},
    35  		current: ConnectionStateMap{
    36  			"a": {
    37  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    38  				PluginModTime: connectionTest1ModTime,
    39  			},
    40  		},
    41  		expected: &ConnectionUpdates{Update: ConnectionStateMap{}, Delete: nil, FinalConnectionState: ConnectionStateMap{
    42  			"a": {
    43  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    44  				PluginModTime: connectionTest1ModTime,
    45  			},
    46  		}},
    47  	},
    48  	"no changes multiple in same file same plugin": {
    49  		required: []string{
    50  			`connection "a" {
    51    plugin = "connection-test-1"
    52  }
    53  
    54  connection "b" {
    55    plugin = "connection-test-1"
    56  }
    57  `},
    58  		current: ConnectionStateMap{
    59  			"a": {
    60  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    61  				PluginModTime: connectionTest1ModTime,
    62  			},
    63  			"b": {
    64  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    65  				PluginModTime: connectionTest1ModTime,
    66  			},
    67  		},
    68  		expected: &ConnectionUpdates{Update: ConnectionStateMap{}, Delete: nil, FinalConnectionState: ConnectionStateMap{
    69  			"a": {
    70  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    71  				PluginModTime: connectionTest1ModTime,
    72  			},
    73  			"b": {
    74  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    75  				PluginModTime: connectionTest1ModTime,
    76  			},
    77  		}},
    78  	},
    79  	"no changes multiple in same file": {
    80  		required: []string{
    81  			`connection "a" {
    82  	 plugin = "connection-test-1"
    83  	}—
    84  	
    85  	connection "b" {
    86  	 plugin = "connection-test-2"
    87  	}
    88  	`},
    89  		current: ConnectionStateMap{
    90  			"a": {
    91  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
    92  				PluginModTime: connectionTest1ModTime,
    93  			},
    94  			"b": {
    95  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
    96  				PluginModTime: connectionTest2ModTime,
    97  			},
    98  		},
    99  		expected: &ConnectionUpdates{Update: ConnectionStateMap{}, Delete: nil, FinalConnectionState: ConnectionStateMap{
   100  			"a": {
   101  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   102  				PluginModTime: connectionTest1ModTime,
   103  			},
   104  			"b": {
   105  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   106  				PluginModTime: connectionTest2ModTime,
   107  			},
   108  		}},
   109  	},
   110  	"no changes multiple in different files same plugin": {
   111  		required: []string{
   112  			`connection "a" {
   113  	 plugin = "connection-test-1"
   114  	}`,
   115  			`connection "b" {
   116  	 plugin = "connection-test-1"
   117  	}
   118  	`},
   119  		current: ConnectionStateMap{
   120  			"a": {
   121  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   122  				PluginModTime: connectionTest1ModTime,
   123  			},
   124  			"b": {
   125  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   126  				PluginModTime: connectionTest1ModTime,
   127  			},
   128  		},
   129  		expected: &ConnectionUpdates{Update: ConnectionStateMap{}, Delete: nil, FinalConnectionState: ConnectionStateMap{
   130  			"a": {
   131  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   132  				PluginModTime: connectionTest1ModTime,
   133  			},
   134  			"b": {
   135  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   136  				PluginModTime: connectionTest1ModTime,
   137  			},
   138  		}},
   139  	},
   140  	"no changes multiple in different files": {
   141  		required: []string{
   142  			`connection "a" {
   143  	 plugin = "connection-test-1"
   144  	}`,
   145  			`connection "b" {
   146  	 plugin = "connection-test-2"
   147  	}
   148  	`},
   149  		current: ConnectionStateMap{
   150  			"a": {
   151  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   152  				PluginModTime: connectionTest1ModTime,
   153  			},
   154  			"b": {
   155  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   156  				PluginModTime: connectionTest2ModTime,
   157  			},
   158  		},
   159  		expected: &ConnectionUpdates{Update: ConnectionStateMap{}, Delete: nil, FinalConnectionState: ConnectionStateMap{
   160  			"a": {
   161  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   162  				PluginModTime: connectionTest1ModTime,
   163  			},
   164  			"b": {
   165  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   166  				PluginModTime: connectionTest2ModTime,
   167  			},
   168  		}},
   169  	},
   170  	"update": {
   171  		required: []string{
   172  			`connection "a" {
   173  	 plugin = "connection-test-1"
   174  	}
   175  	`},
   176  		current: ConnectionStateMap{
   177  			"a": {
   178  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   179  				PluginModTime: time.Now(),
   180  			},
   181  		},
   182  		expected: &ConnectionUpdates{Update: ConnectionStateMap{
   183  			"a": {
   184  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   185  				PluginModTime: connectionTest1ModTime,
   186  			},
   187  		}, Delete: nil, FinalConnectionState: ConnectionStateMap{
   188  			"a": {
   189  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   190  				PluginModTime: connectionTest1ModTime,
   191  			},
   192  		}},
   193  	},
   194  
   195  	"update multiple in same file same plugin": {
   196  		required: []string{
   197  			`connection "a" {
   198  	 plugin = "connection-test-1"
   199  	}
   200  	
   201  	connection "b" {
   202  	 plugin = "connection-test-1"
   203  	}
   204  	`},
   205  		current: ConnectionStateMap{
   206  			"a": {
   207  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   208  				PluginModTime: time.Now(),
   209  			},
   210  			"b": {
   211  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   212  				PluginModTime: time.Now(),
   213  			},
   214  		},
   215  		expected: &ConnectionUpdates{Update: ConnectionStateMap{
   216  			"a": {
   217  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   218  				PluginModTime: connectionTest1ModTime,
   219  			},
   220  			"b": {
   221  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   222  				PluginModTime: connectionTest1ModTime,
   223  			},
   224  		},
   225  			Delete: nil,
   226  			FinalConnectionState: ConnectionStateMap{
   227  				"a": {
   228  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   229  					PluginModTime: connectionTest1ModTime,
   230  				},
   231  				"b": {
   232  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   233  					PluginModTime: connectionTest1ModTime,
   234  				},
   235  			}},
   236  	},
   237  	"update multiple in same file": {
   238  		required: []string{
   239  			`connection "a" {
   240  	 plugin = "connection-test-1"
   241  	}
   242  	
   243  	connection "b" {
   244  	 plugin = "connection-test-2"
   245  	}
   246  	`},
   247  		current: ConnectionStateMap{
   248  			"a": {
   249  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   250  				PluginModTime: time.Now(),
   251  			},
   252  			"b": {
   253  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   254  				PluginModTime: time.Now(),
   255  			},
   256  		},
   257  		expected: &ConnectionUpdates{Update: ConnectionStateMap{
   258  			"a": {
   259  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   260  				PluginModTime: connectionTest1ModTime,
   261  			},
   262  			"b": {
   263  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   264  				PluginModTime: connectionTest2ModTime,
   265  			},
   266  		}, Delete: nil,
   267  			FinalConnectionState: ConnectionStateMap{
   268  				"a": {
   269  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   270  					PluginModTime: connectionTest1ModTime,
   271  				},
   272  				"b": {
   273  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   274  					PluginModTime: connectionTest2ModTime,
   275  				},
   276  			}},
   277  	},
   278  	"update multiple in different files same plugin": {
   279  		required: []string{
   280  			`connection "a" {
   281  	 plugin = "connection-test-1"
   282  	}`,
   283  			`connection "b" {
   284  	 plugin = "connection-test-1"
   285  	}
   286  	`},
   287  		current: ConnectionStateMap{
   288  			"a": {
   289  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   290  				PluginModTime: time.Now(),
   291  			},
   292  			"b": {
   293  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   294  				PluginModTime: time.Now(),
   295  			},
   296  		},
   297  		expected: &ConnectionUpdates{Update: ConnectionStateMap{
   298  			"a": {
   299  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   300  				PluginModTime: connectionTest1ModTime,
   301  			},
   302  			"b": {
   303  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   304  				PluginModTime: connectionTest1ModTime,
   305  			},
   306  		},
   307  			Delete: nil,
   308  			FinalConnectionState: ConnectionStateMap{
   309  				"a": {
   310  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   311  					PluginModTime: connectionTest1ModTime,
   312  				},
   313  				"b": {
   314  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   315  					PluginModTime: connectionTest1ModTime,
   316  				},
   317  			}},
   318  	},
   319  	"update multiple in different files": {
   320  		required: []string{
   321  			`connection "a" {
   322  	 plugin = "connection-test-1"
   323  	}`,
   324  			`connection "b" {
   325  	 plugin = "connection-test-2"
   326  	}
   327  	`},
   328  		current: ConnectionStateMap{
   329  			"a": {
   330  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   331  				PluginModTime: time.Now(),
   332  			},
   333  			"b": {
   334  				Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   335  				PluginModTime: time.Now(),
   336  			},
   337  		},
   338  		expected: &ConnectionUpdates{
   339  			Update: ConnectionStateMap{
   340  				"a": {
   341  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   342  					PluginModTime: connectionTest1ModTime,
   343  				},
   344  				"b": {
   345  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   346  					PluginModTime: connectionTest2ModTime,
   347  				},
   348  			},
   349  			Delete: nil,
   350  			FinalConnectionState: ConnectionStateMap{
   351  				"a": {
   352  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-1@latest",
   353  					PluginModTime: connectionTest1ModTime,
   354  				},
   355  				"b": {
   356  					Plugin:        "hub.steampipe.io/plugins/turbot/connection-test-2@latest",
   357  					PluginModTime: connectionTest2ModTime,
   358  				},
   359  			}},
   360  	},
   361  
   362  	"not installed": {
   363  		required: []string{
   364  			`connection "a" {
   365  	 plugin = "not-installed"
   366  	}
   367  	`},
   368  		current:  ConnectionStateMap{},
   369  		expected: "SHOULD NOT BE ERROR?",
   370  	},
   371  }
   372  
   373  // This test is disabled since the code this one tests also starts up the plugin manager
   374  // process. We need to find a lower denominator to test the functionalities that this one covers
   375  //
   376  // func TestGetConnectionsToUpdate(t *testing.T) {
   377  // 	// set steampipe dir
   378  // 	os.Chdir("./test_data/connections_to_update")
   379  // 	wd, _ := os.Getwd()
   380  // 	filepaths.SteampipeDir = wd
   381  
   382  // 	for name, test := range testCasesGetConnectionsToUpdate {
   383  // 		// setup connection config
   384  // 		setup(test)
   385  // 		defer func(t getConnectionsToUpdateTest) {
   386  // 			teardown(t)
   387  // 		}(test)
   388  
   389  // 		config, err := LoadSteampipeConfig(wd, "")
   390  // 		if err != nil {
   391  // 			t.Fatalf("LoadSteampipeConfig failed with unexpected error: %v", err)
   392  // 		}
   393  // 		if config == nil {
   394  // 			t.Fatalf("Could not load config")
   395  // 		}
   396  // 		GlobalConfig = config
   397  // 		// all tests assume connections a, b
   398  // 		updates, res := NewConnectionUpdates([]string{"a", "b"})
   399  
   400  // 		if res.Error != nil && test.expected != "ERROR" {
   401  // 			t.Fatalf("NewConnectionUpdates failed with unexpected error for \"%s\": %v", name, res.Error)
   402  // 			continue
   403  // 		}
   404  
   405  // 		expectedUpdates := test.expected.(*ConnectionUpdates)
   406  // 		if !updates.RequiredConnectionState.Equals(expectedUpdates.RequiredConnectionState) ||
   407  // 			!updates.Update.Equals(expectedUpdates.Update) ||
   408  // 			!updates.Delete.Equals(expectedUpdates.Delete) {
   409  // 			t.Errorf(`Test: '%s'' FAILED`, name)
   410  
   411  // 		}
   412  
   413  // 		fmt.Printf("\n\n'Test: %s' PASSED\n\n", name)
   414  // 	}
   415  // }
   416  
   417  type connectionDataEqual struct {
   418  	data1       *ConnectionState
   419  	data2       *ConnectionState
   420  	expectation bool
   421  }
   422  
   423  var data1 = ConnectionState{
   424  	Plugin:        "plugin",
   425  	PluginModTime: time.Now().Round(time.Second),
   426  }
   427  var data1_duplicate = ConnectionState{
   428  	Plugin:        "plugin",
   429  	PluginModTime: time.Now().Round(time.Second),
   430  }
   431  var data2 = ConnectionState{
   432  	Plugin:        "plugin2",
   433  	PluginModTime: time.Now().Add(-1 * time.Hour),
   434  }
   435  
   436  var connectionDataEqualCases map[string]connectionDataEqual = map[string]connectionDataEqual{
   437  	"expected_equal":     {data1: &data1, data2: &data1_duplicate, expectation: true},
   438  	"not_expected_equal": {data1: &data1, data2: &data2, expectation: false},
   439  }
   440  
   441  func TestConnectionsUpdateEqual(t *testing.T) {
   442  	for caseName, caseData := range connectionDataEqualCases {
   443  		isEqual := caseData.data1.Equals(caseData.data2)
   444  		if caseData.expectation != isEqual {
   445  			t.Errorf(`Test: '%s' FAILED: expected: %v, actual: %v`, caseName, caseData.expectation, isEqual)
   446  		}
   447  	}
   448  }
   449  
   450  func setup(test getConnectionsToUpdateTest) {
   451  
   452  	os.RemoveAll(filepaths.EnsurePluginDir())
   453  	os.RemoveAll(filepaths.EnsureConfigDir())
   454  	os.RemoveAll(filepaths.EnsureInternalDir())
   455  
   456  	err := os.MkdirAll(filepaths.EnsurePluginDir(), os.ModePerm)
   457  	if err != nil {
   458  		log.Fatal(err)
   459  	}
   460  	err = os.MkdirAll(filepaths.EnsureConfigDir(), os.ModePerm)
   461  	if err != nil {
   462  		log.Fatal(err)
   463  	}
   464  	err = os.MkdirAll(filepaths.EnsureInternalDir(), os.ModePerm)
   465  	if err != nil {
   466  		log.Fatal(err)
   467  	}
   468  
   469  	for _, plugin := range test.current {
   470  		copyPlugin(plugin.Plugin)
   471  	}
   472  	setupTestConfig(test)
   473  }
   474  func teardown(test getConnectionsToUpdateTest) {
   475  	os.RemoveAll(filepaths.EnsurePluginDir())
   476  	os.RemoveAll(filepaths.EnsureConfigDir())
   477  	os.RemoveAll(filepaths.EnsureInternalDir())
   478  
   479  	for _, plugin := range test.current {
   480  		deletePlugin(plugin.Plugin)
   481  	}
   482  	resetConfig(test)
   483  }
   484  
   485  func setupTestConfig(test getConnectionsToUpdateTest) {
   486  	for i, config := range test.required {
   487  		if err := os.WriteFile(connectionConfigPath(i), []byte(config), 0644); err != nil {
   488  			log.Fatal(err)
   489  		}
   490  	}
   491  	err := os.MkdirAll(filepaths.EnsureInternalDir(), os.ModePerm)
   492  	if err != nil {
   493  		log.Fatal(err)
   494  	}
   495  	test.current.Save()
   496  }
   497  
   498  func resetConfig(test getConnectionsToUpdateTest) {
   499  	connectionStatePath := filepaths.ConnectionStatePath()
   500  
   501  	os.Remove(connectionStatePath)
   502  	for i := range test.required {
   503  		os.Remove(connectionConfigPath(i))
   504  	}
   505  }
   506  
   507  func connectionConfigPath(i int) string {
   508  	fileName := fmt.Sprintf("test%d%s", i, constants.ConfigExtension)
   509  	path := filepath.Join(filepaths.EnsureConfigDir(), fileName)
   510  	return path
   511  }
   512  
   513  func copyPlugin(plugin string) {
   514  	source, err := filepath.Abs(filepath.Join("testdata", "connections_to_update", "plugins_src", plugin))
   515  
   516  	if err != nil {
   517  		log.Fatal(err)
   518  	}
   519  	dest, err := filepath.Abs(filepath.Join(filepaths.EnsurePluginDir(), plugin))
   520  	if err != nil {
   521  		log.Fatal(err)
   522  	}
   523  
   524  	err = copy.Copy(source, dest)
   525  	if err != nil {
   526  		log.Fatal(err)
   527  	}
   528  }
   529  func deletePlugin(plugin string) {
   530  	dest, err := filepath.Abs(filepath.Join(filepaths.EnsurePluginDir(), plugin))
   531  	if err != nil {
   532  		log.Fatal(err)
   533  	}
   534  	os.RemoveAll(dest)
   535  }
   536  
   537  func getTestFileModTime(file string) time.Time {
   538  	modTime, _ := utils.FileModTime(file)
   539  	return modTime
   540  }