Skip to content

Commit

Permalink
Fix e2e TestAntctl on windows testbed
Browse files Browse the repository at this point in the history
TestAntctl/testAntctlControllerRemoteAccess failed
on all windows testbed because it cannot get
output of `antctl get memberlist` while collecting
supportbundle from outside on windows testbed as
memberlist is not running.

This PR handles the above case as success on linux
and writes output to file that memberlist is not running.

On Windows, don't collect memberlist as it never runs on Windows.

Fixes #4659

Signed-off-by: Kumar Atish <atish.iaf@gmail.com>
  • Loading branch information
Atish-iaf committed Mar 9, 2023
1 parent 3248549 commit 44e7ce7
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 31 deletions.
8 changes: 7 additions & 1 deletion pkg/agent/apiserver/handlers/memberlist/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package memberlist
import (
"encoding/json"
"net/http"
"reflect"

v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -48,9 +49,14 @@ func generateResponse(node *v1.Node, aliveNodes sets.String) Response {
// HandleFunc returns the function which can handle queries issued by the memberlist command.
func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
memberlistCluster := aq.GetMemberlistCluster()
if reflect.ValueOf(memberlistCluster).IsNil() {
http.Error(w, "memberlist is not running", http.StatusServiceUnavailable)
return
}
var memberlist []Response
allNodes, _ := aq.GetNodeLister().List(labels.Everything())
aliveNodes := aq.GetMemberlistCluster().AliveNodes()
aliveNodes := memberlistCluster.AliveNodes()
for _, node := range allNodes {
memberlist = append(memberlist, generateResponse(node, aliveNodes))
}
Expand Down
88 changes: 62 additions & 26 deletions pkg/agent/apiserver/handlers/memberlist/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
corelisters "k8s.io/client-go/listers/core/v1"

"antrea.io/antrea/pkg/agent/memberlist"
memberlisttest "antrea.io/antrea/pkg/agent/memberlist/testing"
queriertest "antrea.io/antrea/pkg/agent/querier/testing"
)
Expand Down Expand Up @@ -68,35 +70,69 @@ func TestMemberlistQuery(t *testing.T) {
informerFactory.Start(stopCh)
informerFactory.WaitForCacheSync(stopCh)

ctrl := gomock.NewController(t)
q := queriertest.NewMockAgentQuerier(ctrl)
memberlistInterface := memberlisttest.NewMockInterface(ctrl)
q.EXPECT().GetNodeLister().Return(nodeLister)
q.EXPECT().GetMemberlistCluster().Return(memberlistInterface)
memberlistInterface.EXPECT().AliveNodes().Return(sets.NewString("node1"))
handler := HandleFunc(q)

req, err := http.NewRequest(http.MethodGet, "", nil)
require.NoError(t, err)

recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, req)
assert.Equal(t, http.StatusOK, recorder.Code)

expectedResponse := []Response{
tests := []struct {
name string
memberlistInterface func(*gomock.Controller) memberlist.Interface
nodeLister corelisters.NodeLister
expectedStatus int
expectedResponse []Response
}{
{
NodeName: "node1",
IP: "172.16.0.11",
Status: "Alive",
name: "memberlist not running",
memberlistInterface: func(c *gomock.Controller) memberlist.Interface {
var cluster *memberlist.Cluster
var m memberlist.Interface = cluster
return m
},
expectedStatus: http.StatusServiceUnavailable,
},
{
NodeName: "node2",
IP: "172.16.0.12",
Status: "Dead",
name: "get memberlist",
memberlistInterface: func(c *gomock.Controller) memberlist.Interface {
m := memberlisttest.NewMockInterface(c)
m.EXPECT().AliveNodes().Return(sets.NewString("node1"))
return m
},
nodeLister: nodeLister,
expectedStatus: http.StatusOK,
expectedResponse: []Response{
{
NodeName: "node1",
IP: "172.16.0.11",
Status: "Alive",
},
{
NodeName: "node2",
IP: "172.16.0.12",
Status: "Dead",
},
},
},
}
var received []Response
err = json.Unmarshal(recorder.Body.Bytes(), &received)
require.NoError(t, err)
assert.ElementsMatch(t, expectedResponse, received)

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
q := queriertest.NewMockAgentQuerier(ctrl)
q.EXPECT().GetMemberlistCluster().Return(tt.memberlistInterface(ctrl))
if tt.nodeLister != nil {
q.EXPECT().GetNodeLister().Return(tt.nodeLister)
}
handler := HandleFunc(q)

req, err := http.NewRequest(http.MethodGet, "", nil)
require.NoError(t, err)

recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, req)
assert.Equal(t, tt.expectedStatus, recorder.Code)

if tt.expectedStatus == http.StatusOK {
var received []Response
err = json.Unmarshal(recorder.Body.Bytes(), &received)
require.NoError(t, err)
assert.ElementsMatch(t, tt.expectedResponse, received)
}
})
}
}
4 changes: 0 additions & 4 deletions pkg/support/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,6 @@ func (d *agentDumper) DumpAgentInfo(basedir string) error {
return writeYAMLFile(d.fs, filepath.Join(basedir, "agentinfo"), "agentinfo", ai)
}

func (d *agentDumper) DumpMemberlist(basedir string) error {
return dumpAntctlGet(d.fs, d.executor, "memberlist", basedir)
}

func (d *agentDumper) DumpNetworkPolicyResources(basedir string) error {
dump := func(o interface{}, name string) error {
return writeYAMLFile(d.fs, filepath.Join(basedir, name), name, o)
Expand Down
9 changes: 9 additions & 0 deletions pkg/support/dump_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"path"
"path/filepath"
"strings"

"antrea.io/antrea/pkg/agent/util/iptables"
"antrea.io/antrea/pkg/util/logdir"
Expand Down Expand Up @@ -73,3 +74,11 @@ func (d *agentDumper) dumpIPToolInfo(basedir string) error {
}
return nil
}

func (d *agentDumper) DumpMemberlist(basedir string) error {
output, err := d.executor.Command("antctl", "-oyaml", "get", "memberlist").CombinedOutput()
if err != nil && !strings.Contains(string(output), "memberlist is not running") {
return fmt.Errorf("error when dumping memberlist: %w", err)
}
return writeFile(d.fs, filepath.Join(basedir, "memberlist"), "memberlist", output)
}
5 changes: 5 additions & 0 deletions pkg/support/dump_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,8 @@ func (d *agentDumper) dumpHNSResources(basedir string) error {
}
return nil
}

func (d *agentDumper) DumpMemberlist(basedir string) error {
// memberlist never runs on windows.
return nil
}

0 comments on commit 44e7ce7

Please sign in to comment.