github.com/crowdsecurity/crowdsec@v1.6.1/pkg/cwhub/itemupgrade_test.go (about)

     1  package cwhub
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
     9  )
    10  
    11  // Download index, install collection. Add scenario to collection (hub-side), update index, upgrade collection.
    12  // We expect the new scenario to be installed.
    13  func TestUpgradeItemNewScenarioInCollection(t *testing.T) {
    14  	hub := envSetup(t)
    15  	item := hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection")
    16  
    17  	// fresh install of collection
    18  	require.False(t, item.State.Downloaded)
    19  	require.False(t, item.State.Installed)
    20  
    21  	require.NoError(t, item.Install(false, false))
    22  
    23  	require.True(t, item.State.Downloaded)
    24  	require.True(t, item.State.Installed)
    25  	require.True(t, item.State.UpToDate)
    26  	require.False(t, item.State.Tainted)
    27  
    28  	// This is the scenario that gets added in next version of collection
    29  	require.Nil(t, hub.GetItem(SCENARIOS, "crowdsecurity/barfoo_scenario"))
    30  
    31  	assertCollectionDepsInstalled(t, hub, "crowdsecurity/test_collection")
    32  
    33  	// collection receives an update. It now adds new scenario "crowdsecurity/barfoo_scenario"
    34  	pushUpdateToCollectionInHub()
    35  
    36  	remote := &RemoteHubCfg{
    37  		URLTemplate: mockURLTemplate,
    38  		Branch:      "master",
    39  		IndexPath:   ".index.json",
    40  	}
    41  
    42  	hub, err := NewHub(hub.local, remote, true, nil)
    43  	require.NoError(t, err, "failed to download index: %s", err)
    44  
    45  	hub = getHubOrFail(t, hub.local, remote)
    46  
    47  	item = hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection")
    48  
    49  	require.True(t, item.State.Downloaded)
    50  	require.True(t, item.State.Installed)
    51  	require.False(t, item.State.UpToDate)
    52  	require.False(t, item.State.Tainted)
    53  
    54  	didUpdate, err := item.Upgrade(false)
    55  	require.NoError(t, err)
    56  	require.True(t, didUpdate)
    57  	assertCollectionDepsInstalled(t, hub, "crowdsecurity/test_collection")
    58  
    59  	require.True(t, hub.GetItem(SCENARIOS, "crowdsecurity/barfoo_scenario").State.Downloaded)
    60  	require.True(t, hub.GetItem(SCENARIOS, "crowdsecurity/barfoo_scenario").State.Installed)
    61  }
    62  
    63  // Install a collection, disable a scenario.
    64  // Upgrade should install should not enable/download the disabled scenario.
    65  func TestUpgradeItemInDisabledScenarioShouldNotBeInstalled(t *testing.T) {
    66  	hub := envSetup(t)
    67  	item := hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection")
    68  
    69  	// fresh install of collection
    70  	require.False(t, item.State.Downloaded)
    71  	require.False(t, item.State.Installed)
    72  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
    73  
    74  	require.NoError(t, item.Install(false, false))
    75  
    76  	require.True(t, item.State.Downloaded)
    77  	require.True(t, item.State.Installed)
    78  	require.True(t, item.State.UpToDate)
    79  	require.False(t, item.State.Tainted)
    80  	require.True(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
    81  	assertCollectionDepsInstalled(t, hub, "crowdsecurity/test_collection")
    82  
    83  	item = hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario")
    84  	didRemove, err := item.Remove(false, false)
    85  	require.NoError(t, err)
    86  	require.True(t, didRemove)
    87  
    88  	remote := &RemoteHubCfg{
    89  		URLTemplate: mockURLTemplate,
    90  		Branch:      "master",
    91  		IndexPath:   ".index.json",
    92  	}
    93  
    94  	hub = getHubOrFail(t, hub.local, remote)
    95  	// scenario referenced by collection  was deleted hence, collection should be tainted
    96  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
    97  
    98  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.Tainted)
    99  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.Downloaded)
   100  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.Installed)
   101  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.UpToDate)
   102  
   103  	hub, err = NewHub(hub.local, remote, true, nil)
   104  	require.NoError(t, err, "failed to download index: %s", err)
   105  
   106  	item = hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection")
   107  	didUpdate, err := item.Upgrade(false)
   108  	require.NoError(t, err)
   109  	require.False(t, didUpdate)
   110  
   111  	hub = getHubOrFail(t, hub.local, remote)
   112  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
   113  }
   114  
   115  // getHubOrFail refreshes the hub state (load index, sync) and returns the singleton, or fails the test.
   116  func getHubOrFail(t *testing.T, local *csconfig.LocalHubCfg, remote *RemoteHubCfg) *Hub {
   117  	hub, err := NewHub(local, remote, false, nil)
   118  	require.NoError(t, err, "failed to load hub index")
   119  
   120  	return hub
   121  }
   122  
   123  // Install a collection. Disable a referenced scenario. Publish new version of collection with new scenario
   124  // Upgrade should not enable/download the disabled scenario.
   125  // Upgrade should install and enable the newly added scenario.
   126  func TestUpgradeItemNewScenarioIsInstalledWhenReferencedScenarioIsDisabled(t *testing.T) {
   127  	hub := envSetup(t)
   128  	item := hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection")
   129  
   130  	// fresh install of collection
   131  	require.False(t, item.State.Downloaded)
   132  	require.False(t, item.State.Installed)
   133  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
   134  
   135  	require.NoError(t, item.Install(false, false))
   136  
   137  	require.True(t, item.State.Downloaded)
   138  	require.True(t, item.State.Installed)
   139  	require.True(t, item.State.UpToDate)
   140  	require.False(t, item.State.Tainted)
   141  	require.True(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
   142  	assertCollectionDepsInstalled(t, hub, "crowdsecurity/test_collection")
   143  
   144  	item = hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario")
   145  	didRemove, err := item.Remove(false, false)
   146  	require.NoError(t, err)
   147  	require.True(t, didRemove)
   148  
   149  	remote := &RemoteHubCfg{
   150  		URLTemplate: mockURLTemplate,
   151  		Branch:      "master",
   152  		IndexPath:   ".index.json",
   153  	}
   154  
   155  	hub = getHubOrFail(t, hub.local, remote)
   156  	// scenario referenced by collection  was deleted hence, collection should be tainted
   157  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
   158  	require.True(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Downloaded) // this fails
   159  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.Tainted)
   160  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.Downloaded)
   161  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.Installed)
   162  	require.True(t, hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection").State.UpToDate)
   163  
   164  	// collection receives an update. It now adds new scenario "crowdsecurity/barfoo_scenario"
   165  	// we now attempt to upgrade the collection, however it shouldn't install the foobar_scenario
   166  	// we just removed. Nor should it install the newly added scenario
   167  	pushUpdateToCollectionInHub()
   168  
   169  	hub, err = NewHub(hub.local, remote, true, nil)
   170  	require.NoError(t, err, "failed to download index: %s", err)
   171  
   172  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
   173  	hub = getHubOrFail(t, hub.local, remote)
   174  
   175  	item = hub.GetItem(COLLECTIONS, "crowdsecurity/test_collection")
   176  	didUpdate, err := item.Upgrade(false)
   177  	require.NoError(t, err)
   178  	require.True(t, didUpdate)
   179  
   180  	hub = getHubOrFail(t, hub.local, remote)
   181  	require.False(t, hub.GetItem(SCENARIOS, "crowdsecurity/foobar_scenario").State.Installed)
   182  	require.True(t, hub.GetItem(SCENARIOS, "crowdsecurity/barfoo_scenario").State.Installed)
   183  }
   184  
   185  func assertCollectionDepsInstalled(t *testing.T, hub *Hub, collection string) {
   186  	t.Helper()
   187  
   188  	c := hub.GetItem(COLLECTIONS, collection)
   189  	require.Empty(t, c.checkSubItemVersions())
   190  }
   191  
   192  func pushUpdateToCollectionInHub() {
   193  	responseByPath["/master/.index.json"] = fileToStringX("./testdata/index2.json")
   194  	responseByPath["/master/collections/crowdsecurity/test_collection.yaml"] = fileToStringX("./testdata/collection_v2.yaml")
   195  }