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

     1  package cwhub
     2  
     3  import (
     4  	"io"
     5  	"net/http"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  
    11  	log "github.com/sirupsen/logrus"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
    15  )
    16  
    17  const mockURLTemplate = "https://hub-cdn.crowdsec.net/%s/%s"
    18  
    19  /*
    20   To test :
    21    - Download 'first' hub index
    22    - Update hub index
    23    - Install collection + list content
    24    - Taint existing parser + list
    25    - Upgrade collection
    26  */
    27  
    28  var responseByPath map[string]string
    29  
    30  // testHub initializes a temporary hub with an empty json file, optionally updating it.
    31  func testHub(t *testing.T, update bool) *Hub {
    32  	tmpDir, err := os.MkdirTemp("", "testhub")
    33  	require.NoError(t, err)
    34  
    35  	local := &csconfig.LocalHubCfg{
    36  		HubDir:         filepath.Join(tmpDir, "crowdsec", "hub"),
    37  		HubIndexFile:   filepath.Join(tmpDir, "crowdsec", "hub", ".index.json"),
    38  		InstallDir:     filepath.Join(tmpDir, "crowdsec"),
    39  		InstallDataDir: filepath.Join(tmpDir, "installed-data"),
    40  	}
    41  
    42  	err = os.MkdirAll(local.HubDir, 0o700)
    43  	require.NoError(t, err)
    44  
    45  	err = os.MkdirAll(local.InstallDir, 0o700)
    46  	require.NoError(t, err)
    47  
    48  	err = os.MkdirAll(local.InstallDataDir, 0o700)
    49  	require.NoError(t, err)
    50  
    51  	err = os.WriteFile(local.HubIndexFile, []byte("{}"), 0o644)
    52  	require.NoError(t, err)
    53  
    54  	t.Cleanup(func() {
    55  		os.RemoveAll(tmpDir)
    56  	})
    57  
    58  	remote := &RemoteHubCfg{
    59  		Branch:      "master",
    60  		URLTemplate: mockURLTemplate,
    61  		IndexPath:   ".index.json",
    62  	}
    63  
    64  	hub, err := NewHub(local, remote, update, log.StandardLogger())
    65  	require.NoError(t, err)
    66  
    67  	return hub
    68  }
    69  
    70  // envSetup initializes the temporary hub and mocks the http client.
    71  func envSetup(t *testing.T) *Hub {
    72  	setResponseByPath()
    73  	log.SetLevel(log.DebugLevel)
    74  
    75  	defaultTransport := hubClient.Transport
    76  
    77  	t.Cleanup(func() {
    78  		hubClient.Transport = defaultTransport
    79  	})
    80  
    81  	// Mock the http client
    82  	hubClient.Transport = newMockTransport()
    83  
    84  	hub := testHub(t, true)
    85  
    86  	return hub
    87  }
    88  
    89  type mockTransport struct{}
    90  
    91  func newMockTransport() http.RoundTripper {
    92  	return &mockTransport{}
    93  }
    94  
    95  // Implement http.RoundTripper.
    96  func (t *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    97  	// Create mocked http.Response
    98  	response := &http.Response{
    99  		Header:     make(http.Header),
   100  		Request:    req,
   101  		StatusCode: http.StatusOK,
   102  	}
   103  	response.Header.Set("Content-Type", "application/json")
   104  
   105  	log.Infof("---> %s", req.URL.Path)
   106  
   107  	// FAKE PARSER
   108  	resp, ok := responseByPath[req.URL.Path]
   109  	if !ok {
   110  		log.Fatalf("unexpected url :/ %s", req.URL.Path)
   111  	}
   112  
   113  	response.Body = io.NopCloser(strings.NewReader(resp))
   114  
   115  	return response, nil
   116  }
   117  
   118  func fileToStringX(path string) string {
   119  	f, err := os.Open(path)
   120  	if err != nil {
   121  		panic(err)
   122  	}
   123  	defer f.Close()
   124  
   125  	data, err := io.ReadAll(f)
   126  	if err != nil {
   127  		panic(err)
   128  	}
   129  
   130  	return strings.ReplaceAll(string(data), "\r\n", "\n")
   131  }
   132  
   133  func setResponseByPath() {
   134  	responseByPath = map[string]string{
   135  		"/master/parsers/s01-parse/crowdsecurity/foobar_parser.yaml":    fileToStringX("./testdata/foobar_parser.yaml"),
   136  		"/master/parsers/s01-parse/crowdsecurity/foobar_subparser.yaml": fileToStringX("./testdata/foobar_parser.yaml"),
   137  		"/master/collections/crowdsecurity/test_collection.yaml":        fileToStringX("./testdata/collection_v1.yaml"),
   138  		"/master/.index.json": fileToStringX("./testdata/index1.json"),
   139  		"/master/scenarios/crowdsecurity/foobar_scenario.yaml": `filter: true
   140  name: crowdsecurity/foobar_scenario`,
   141  		"/master/scenarios/crowdsecurity/barfoo_scenario.yaml": `filter: true
   142  name: crowdsecurity/foobar_scenario`,
   143  		"/master/collections/crowdsecurity/foobar_subcollection.yaml": `
   144  blah: blalala
   145  qwe: jejwejejw`,
   146  		"/master/collections/crowdsecurity/foobar.yaml": `
   147  blah: blalala
   148  qwe: jejwejejw`,
   149  	}
   150  }