diff --git a/balloon/balloon.go b/balloon/balloon.go index 232c16f59..1e99e1cb0 100644 --- a/balloon/balloon.go +++ b/balloon/balloon.go @@ -47,12 +47,9 @@ type Balloon struct { func NewBalloon(store storage.Store, hasherF func() hashing.Hasher) (*Balloon, error) { - // create caches - hyperCache := cache.NewFreeCache(hyper.CacheSize) - // create trees historyTree := history.NewHistoryTree(hasherF, store, 300) - hyperTree := hyper.NewHyperTree(hasherF, store, hyperCache) + hyperTree := hyper.NewHyperTree(hasherF, store, cache.NewFreeCache(hyper.CacheSize)) balloon := &Balloon{ version: 0, diff --git a/raftwal/fsm.go b/raftwal/fsm.go index 722370033..dcbd6ca29 100644 --- a/raftwal/fsm.go +++ b/raftwal/fsm.go @@ -239,7 +239,8 @@ func (fsm *BalloonFSM) Restore(rc io.ReadCloser) error { } func (fsm *BalloonFSM) Close() error { - return fsm.store.Close() + fsm.balloon.Close() + return nil } func (fsm *BalloonFSM) applyAdd(event []byte, state *fsmState) *fsmAddResponse { diff --git a/raftwal/raft.go b/raftwal/raft.go index 8ae68a6b9..eae700722 100644 --- a/raftwal/raft.go +++ b/raftwal/raft.go @@ -214,12 +214,6 @@ func (b *RaftBalloon) Close(wait bool) error { close(b.done) b.wg.Wait() - // close database - if err := b.store.db.Close(); err != nil { - return err - } - b.store.db = nil - // shutdown raft if b.raft.api != nil { f := b.raft.api.Shutdown() @@ -238,9 +232,19 @@ func (b *RaftBalloon) Close(wait bool) error { if err := b.store.stable.Close(); err != nil { return err } + b.store.log = nil b.store.stable = nil + // Close FSM + b.fsm.Close() + + // close database + if err := b.store.db.Close(); err != nil { + return err + } + b.store.db = nil + return nil } diff --git a/tests/e2e/agents_test.go b/tests/e2e/agents_test.go index 0ef3f1f29..026fbdfce 100644 --- a/tests/e2e/agents_test.go +++ b/tests/e2e/agents_test.go @@ -19,7 +19,6 @@ import ( "fmt" "io/ioutil" "net/http" - "os/exec" "strings" "testing" "time" @@ -123,17 +122,10 @@ func TestAgents(t *testing.T) { }) let("Tamper 1st event", func(t *testing.T) { - cmd := exec.Command("curl", - "-sS", - "-XDELETE", - "-H", fmt.Sprintf("Api-Key:%s", APIKey), - "-H", "Content-type: application/json", - QEDTamperURL, - "-d", fmt.Sprintf(`{"Digest": "%X"}`, hashing.NewSha256Hasher().Do(hashing.Digest(event))), - ) - - _, err := cmd.CombinedOutput() - assert.NoError(t, err, "Subprocess must not exit with status 1") + buff := strings.NewReader(fmt.Sprintf(`{"Digest": "%X"}`, hashing.NewSha256Hasher().Do(hashing.Digest(event)))) + resp, err := doReq("DELETE", QEDTamperURL, APIKey, buff) + assert.NoError(t, err) + assert.Equal(t, resp.StatusCode, http.StatusOK, "Server should respond with http status code 200") }) let("Check Auditor alerts", func(t *testing.T) { @@ -165,21 +157,10 @@ func TestAgents(t *testing.T) { }) let("Tamper 1st event", func(t *testing.T) { - cmd := exec.Command("curl", - "-sS", - "-XPATCH", - "-H", fmt.Sprintf("Api-Key: %s", APIKey), - "-H", "Content-type: application/json", - QEDTamperURL, - "-d", fmt.Sprintf(`{"Digest": "%X","Value": "%X"}`, - hasher.Do(hashing.Digest(event)), - hasher.Do(hashing.Digest(tampered)), - ), - ) - - _, err := cmd.CombinedOutput() - - assert.NoError(t, err, "Subprocess must not exit with status 1") + buff := strings.NewReader(fmt.Sprintf(`{"Digest": "%X","Value": "%X"}`, hasher.Do(hashing.Digest(event)), hasher.Do(hashing.Digest(tampered)))) + resp, err := doReq("PATCH", QEDTamperURL, APIKey, buff) + assert.NoError(t, err) + assert.Equal(t, resp.StatusCode, http.StatusOK, "Server should respond with http status code 200") }) let("Add 2nd event", func(t *testing.T) { diff --git a/tests/e2e/cli_test.go b/tests/e2e/cli_test.go index e09773c04..4081b4b1e 100644 --- a/tests/e2e/cli_test.go +++ b/tests/e2e/cli_test.go @@ -210,18 +210,17 @@ func Test_Client_To_Cluster_With_Bad_Endpoint(t *testing.T) { before0, after0 := setupServer(0, "", false, t) before1, after1 := setupServer(1, "", false, t) - serversHttpAddr := "badendpoint,http://127.0.0.1:8800" - scenario, let := scope.Scope(t, merge(before0, before1), merge(after0, after1, delay(2*time.Second))) scenario("Success by extracting topology from right endpoint", func() { - let("Add event", func(t *testing.T) { + + let("Add event with one valid endpoint", func(t *testing.T) { cmd := exec.Command("go", "run", "./../../main.go", fmt.Sprintf("--apikey=%s", APIKey), "client", - fmt.Sprintf("--endpoints=%s", serversHttpAddr), + fmt.Sprintf("--endpoints=badendpoint,http://127.0.0.1:8800"), "add", "--key='test event'", "--value=2", @@ -232,17 +231,14 @@ func Test_Client_To_Cluster_With_Bad_Endpoint(t *testing.T) { require.NoErrorf(t, err, "Subprocess must not exit with status 1: %v", *cmd) }) - }) - serversHttpAddr = "badendpoint" - scenario("Fails if no right endpoint provided", func() { - let("Add event", func(t *testing.T) { + let("Add event with no valid endpoint and fail", func(t *testing.T) { cmd := exec.Command("go", "run", "./../../main.go", fmt.Sprintf("--apikey=%s", APIKey), "client", - fmt.Sprintf("--endpoints=%s", serversHttpAddr), + fmt.Sprintf("--endpoints=badendpoint"), "add", "--key='test event'", "--value=2", diff --git a/tests/e2e/server_test.go b/tests/e2e/server_test.go index 79432fd1a..68d8b0dc4 100644 --- a/tests/e2e/server_test.go +++ b/tests/e2e/server_test.go @@ -17,8 +17,7 @@ package e2e import ( - "fmt" - "os/exec" + "net/http" "testing" "time" @@ -43,47 +42,24 @@ func TestStart(t *testing.T) { scenario("Test availability of profiling server", func() { let("Query to expected context", func(t *testing.T) { - cmd := exec.Command("curl", - "--fail", - "-sS", - "-XGET", - "-H", fmt.Sprintf("Api-Key:%s", APIKey), - "-H", "Content-type: application/json", - QEDProfilingURL, - ) - - _, err := cmd.CombinedOutput() - assert.NoError(t, err, "Subprocess must not exit with non-zero status") + resp, err := doReq("GET", QEDProfilingURL, APIKey, nil) + assert.NoError(t, err) + assert.Equal(t, resp.StatusCode, http.StatusOK, "Server should respond with http status code 200") }) let("Query to unexpected context", func(t *testing.T) { - cmd := exec.Command("curl", - "--fail", - "-sS", - "-XGET", - "-H", fmt.Sprintf("Api-Key:%s", APIKey), - "-H", "Content-type: application/json", - QEDProfilingURL+"/xD", - ) + resp, err := doReq("GET", QEDProfilingURL+"/xD", APIKey, nil) + assert.NoError(t, err) + assert.Equal(t, resp.StatusCode, http.StatusNotFound, "Server should respond with http status code 404") - _, err := cmd.CombinedOutput() - assert.Error(t, err, "Subprocess must exit with non-zero status") }) }) scenario("Test availability of metrics server", func() { let("Query metrics endpoint", func(t *testing.T) { - cmd := exec.Command("curl", - "--fail", - "-sS", - "-XGET", - "-H", fmt.Sprintf("Api-Key:%s", APIKey), - "-H", "Content-type: application/json", - QEDMetricsURL, - ) - - _, err := cmd.CombinedOutput() + resp, err := doReq("GET", QEDMetricsURL, APIKey, nil) assert.NoError(t, err, "Subprocess must not exit with non-zero status") + assert.Equal(t, resp.StatusCode, http.StatusOK, "Server should respond with http status code 200") }) }) diff --git a/tests/e2e/setup.go b/tests/e2e/setup.go index 7bc2c57e4..2ab496cbf 100644 --- a/tests/e2e/setup.go +++ b/tests/e2e/setup.go @@ -18,8 +18,12 @@ package e2e import ( "fmt" + "io/ioutil" + "net/http" "os" "os/user" + "runtime/debug" + "strings" "testing" "time" @@ -42,6 +46,10 @@ const ( APIKey = "my-key" ) +func init() { + debug.SetGCPercent(10) +} + // merge function is a helper function that execute all the variadic parameters // inside a score.TestF function func merge(list ...scope.TestF) scope.TestF { @@ -58,6 +66,28 @@ func delay(duration time.Duration) scope.TestF { } } +func doReq(method string, url, apiKey string, payload *strings.Reader) (*http.Response, error) { + var err error + if payload == nil { + payload = strings.NewReader("") + } + req, err := http.NewRequest(method, url, payload) + if err != nil { + return nil, err + } + + req.Header.Set("Api-Key", apiKey) + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + return resp, err +} + func newAgent(id int, name string, role member.Type, p gossip.Processor, t *testing.T) *gossip.Agent { agentConf := gossip.DefaultConfig() agentConf.NodeName = fmt.Sprintf("%s%d", name, id) @@ -207,17 +237,13 @@ func setupStore(t *testing.T) (scope.TestF, scope.TestF) { func setupServer(id int, joinAddr string, tls bool, t *testing.T) (scope.TestF, scope.TestF) { var srv *server.Server var err error - path := fmt.Sprintf("/var/tmp/e2e-qed%d/", id) - + path, err := ioutil.TempDir("", "e2e-qed") + if err != nil { + t.Fatalf("Unable to create a path: %v", err) + } usr, _ := user.Current() before := func(t *testing.T) { - os.RemoveAll(path) - err = os.MkdirAll(path, os.FileMode(0755)) - if err != nil { - t.Fatalf("Unable to create a path: %v", err) - } - hostname, _ := os.Hostname() conf := server.DefaultConfig() conf.APIKey = APIKey @@ -242,8 +268,6 @@ func setupServer(id int, joinAddr string, tls bool, t *testing.T) (scope.TestF, conf.EnableTampering = true conf.EnableTLS = tls - //fmt.Printf("Server config: %+v\n", conf) - srv, err = server.NewServer(conf) if err != nil { t.Fatalf("Unable to create a new server: %v", err) @@ -259,6 +283,8 @@ func setupServer(id int, joinAddr string, tls bool, t *testing.T) (scope.TestF, } after := func(t *testing.T) { + debug.FreeOSMemory() + os.RemoveAll(path) if srv != nil { err := srv.Stop() if err != nil { @@ -271,13 +297,9 @@ func setupServer(id int, joinAddr string, tls bool, t *testing.T) (scope.TestF, return before, after } -func endPoint(id int) string { - return fmt.Sprintf("http://127.0.0.1:880%d", id) -} - func getClient(id int) *client.HTTPClient { return client.NewHTTPClient(client.Config{ - Endpoints: []string{endPoint(id)}, + Endpoints: []string{fmt.Sprintf("http://127.0.0.1:880%d", id)}, APIKey: APIKey, Insecure: false, })