open-nomad/nomad/system_endpoint_test.go

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

224 lines
6 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
2016-02-20 23:50:41 +00:00
package nomad
import (
"fmt"
"reflect"
2016-02-20 23:50:41 +00:00
"testing"
2017-02-08 05:22:48 +00:00
memdb "github.com/hashicorp/go-memdb"
2019-01-15 19:46:12 +00:00
msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/nomad/acl"
"github.com/hashicorp/nomad/ci"
2016-02-20 23:50:41 +00:00
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/testutil"
"github.com/stretchr/testify/assert"
2016-02-20 23:50:41 +00:00
)
func TestSystemEndpoint_GarbageCollect(t *testing.T) {
ci.Parallel(t)
s1, cleanupS1 := TestServer(t, nil)
defer cleanupS1()
2016-02-20 23:50:41 +00:00
codec := rpcClient(t, s1)
testutil.WaitForLeader(t, s1.RPC)
// Insert a job that can be GC'd
state := s1.fsm.State()
job := mock.Job()
job.Type = structs.JobTypeBatch
2017-04-15 23:47:19 +00:00
job.Stop = true
if err := state.UpsertJob(structs.MsgTypeTestSetup, 1000, nil, job); err != nil {
2017-04-15 23:47:19 +00:00
t.Fatalf("UpsertJob() failed: %v", err)
}
eval := mock.Eval()
eval.Status = structs.EvalStatusComplete
eval.JobID = job.ID
if err := state.UpsertEvals(structs.MsgTypeTestSetup, 1001, []*structs.Evaluation{eval}); err != nil {
2017-04-15 23:47:19 +00:00
t.Fatalf("UpsertEvals() failed: %v", err)
2016-02-20 23:50:41 +00:00
}
// Make the GC request
req := &structs.GenericRequest{
QueryOptions: structs.QueryOptions{
Region: "global",
},
}
var resp structs.GenericResponse
if err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp); err != nil {
t.Fatalf("expect err")
}
testutil.WaitForResult(func() (bool, error) {
// Check if the job has been GC'd
2017-02-08 05:22:48 +00:00
ws := memdb.NewWatchSet()
2017-09-07 23:56:15 +00:00
exist, err := state.JobByID(ws, job.Namespace, job.ID)
2016-02-20 23:50:41 +00:00
if err != nil {
return false, err
}
if exist != nil {
2017-04-15 23:47:19 +00:00
return false, fmt.Errorf("job %+v wasn't garbage collected", job)
2016-02-20 23:50:41 +00:00
}
return true, nil
}, func(err error) {
t.Fatalf("err: %s", err)
})
}
func TestSystemEndpoint_GarbageCollect_ACL(t *testing.T) {
ci.Parallel(t)
s1, root, cleanupS1 := TestACLServer(t, nil)
defer cleanupS1()
codec := rpcClient(t, s1)
assert := assert.New(t)
testutil.WaitForLeader(t, s1.RPC)
state := s1.fsm.State()
// Create ACL tokens
invalidToken := mock.CreatePolicyAndToken(t, state, 1001, "test-invalid", mock.NodePolicy(acl.PolicyWrite))
// Make the GC request
req := &structs.GenericRequest{
QueryOptions: structs.QueryOptions{
Region: "global",
},
}
// Try without a token and expect failure
{
var resp structs.GenericResponse
err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp)
assert.NotNil(err)
assert.Contains(err.Error(), structs.ErrPermissionDenied.Error())
}
// Try with an invalid token and expect failure
{
2017-10-12 22:16:33 +00:00
req.AuthToken = invalidToken.SecretID
var resp structs.GenericResponse
err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp)
assert.NotNil(err)
assert.Contains(err.Error(), structs.ErrPermissionDenied.Error())
}
// Try with a management token
{
2017-10-12 22:16:33 +00:00
req.AuthToken = root.SecretID
var resp structs.GenericResponse
assert.Nil(msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp))
}
}
func TestSystemEndpoint_ReconcileSummaries(t *testing.T) {
ci.Parallel(t)
s1, cleanupS1 := TestServer(t, nil)
defer cleanupS1()
codec := rpcClient(t, s1)
testutil.WaitForLeader(t, s1.RPC)
// Insert a job that can be GC'd
state := s1.fsm.State()
s1.fsm.State()
job := mock.Job()
if err := state.UpsertJob(structs.MsgTypeTestSetup, 1000, nil, job); err != nil {
t.Fatalf("UpsertJob() failed: %v", err)
}
// Delete the job summary
2017-09-07 23:56:15 +00:00
state.DeleteJobSummary(1001, job.Namespace, job.ID)
// Make the GC request
req := &structs.GenericRequest{
QueryOptions: structs.QueryOptions{
Region: "global",
},
}
var resp structs.GenericResponse
if err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp); err != nil {
t.Fatalf("expect err: %v", err)
}
testutil.WaitForResult(func() (bool, error) {
// Check if Nomad has reconciled the summary for the job
2017-02-08 05:22:48 +00:00
ws := memdb.NewWatchSet()
2017-09-07 23:56:15 +00:00
summary, err := state.JobSummaryByID(ws, job.Namespace, job.ID)
if err != nil {
return false, err
}
if summary.CreateIndex == 0 || summary.ModifyIndex == 0 {
t.Fatalf("create index: %v, modify index: %v", summary.CreateIndex, summary.ModifyIndex)
}
// setting the modifyindex and createindex of the expected summary to
// the output so that we can do deep equal
expectedSummary := structs.JobSummary{
2017-09-07 23:56:15 +00:00
JobID: job.ID,
Namespace: job.Namespace,
Summary: map[string]structs.TaskGroupSummary{
2017-09-26 22:26:33 +00:00
"web": {
Queued: 10,
},
},
ModifyIndex: summary.ModifyIndex,
CreateIndex: summary.CreateIndex,
}
if !reflect.DeepEqual(&expectedSummary, summary) {
return false, fmt.Errorf("expected: %v, actual: %v", expectedSummary, summary)
}
return true, nil
}, func(err error) {
t.Fatalf("err: %s", err)
})
}
func TestSystemEndpoint_ReconcileJobSummaries_ACL(t *testing.T) {
ci.Parallel(t)
s1, root, cleanupS1 := TestACLServer(t, nil)
defer cleanupS1()
codec := rpcClient(t, s1)
assert := assert.New(t)
testutil.WaitForLeader(t, s1.RPC)
state := s1.fsm.State()
// Create ACL tokens
invalidToken := mock.CreatePolicyAndToken(t, state, 1001, "test-invalid", mock.NodePolicy(acl.PolicyWrite))
// Make the request
req := &structs.GenericRequest{
QueryOptions: structs.QueryOptions{
Region: "global",
},
}
// Try without a token and expect failure
{
var resp structs.GenericResponse
err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp)
assert.NotNil(err)
assert.Contains(err.Error(), structs.ErrPermissionDenied.Error())
}
// Try with an invalid token and expect failure
{
2017-10-12 22:16:33 +00:00
req.AuthToken = invalidToken.SecretID
var resp structs.GenericResponse
err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp)
assert.NotNil(err)
assert.Contains(err.Error(), structs.ErrPermissionDenied.Error())
}
// Try with a management token
{
2017-10-12 22:16:33 +00:00
req.AuthToken = root.SecretID
var resp structs.GenericResponse
assert.Nil(msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp))
}
}