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 }