github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/e2e/namespaces/namespaces.go (about) 1 package namespaces 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 8 e2e "github.com/hashicorp/nomad/e2e/e2eutil" 9 "github.com/hashicorp/nomad/e2e/framework" 10 "github.com/hashicorp/nomad/helper/uuid" 11 ) 12 13 type NamespacesE2ETest struct { 14 framework.TC 15 namespaceIDs []string 16 namespacedJobIDs [][2]string // [(ns, jobID)] 17 } 18 19 func init() { 20 framework.AddSuites(&framework.TestSuite{ 21 Component: "Namespaces", 22 CanRunLocal: true, 23 Consul: true, 24 Cases: []framework.TestCase{ 25 new(NamespacesE2ETest), 26 }, 27 }) 28 29 } 30 31 func (tc *NamespacesE2ETest) BeforeAll(f *framework.F) { 32 e2e.WaitForLeader(f.T(), tc.Nomad()) 33 e2e.WaitForNodesReady(f.T(), tc.Nomad(), 1) 34 } 35 36 func (tc *NamespacesE2ETest) AfterEach(f *framework.F) { 37 if os.Getenv("NOMAD_TEST_SKIPCLEANUP") == "1" { 38 return 39 } 40 41 for _, pair := range tc.namespacedJobIDs { 42 ns := pair[0] 43 jobID := pair[1] 44 if ns != "" { 45 _, err := e2e.Command("nomad", "job", "stop", "-purge", "-namespace", ns, jobID) 46 f.Assert().NoError(err) 47 } else { 48 _, err := e2e.Command("nomad", "job", "stop", "-purge", jobID) 49 f.Assert().NoError(err) 50 } 51 } 52 tc.namespacedJobIDs = [][2]string{} 53 54 for _, ns := range tc.namespaceIDs { 55 _, err := e2e.Command("nomad", "namespace", "delete", ns) 56 f.Assert().NoError(err) 57 } 58 tc.namespaceIDs = []string{} 59 60 _, err := e2e.Command("nomad", "system", "gc") 61 f.Assert().NoError(err) 62 } 63 64 // TestNamespacesFiltering exercises the -namespace flag on various commands 65 // to ensure that they are properly isolated 66 func (tc *NamespacesE2ETest) TestNamespacesFiltering(f *framework.F) { 67 68 _, err := e2e.Command("nomad", "namespace", "apply", 69 "-description", "namespace A", "NamespaceA") 70 f.NoError(err, "could not create namespace") 71 tc.namespaceIDs = append(tc.namespaceIDs, "NamespaceA") 72 73 _, err = e2e.Command("nomad", "namespace", "apply", 74 "-description", "namespace B", "NamespaceB") 75 f.NoError(err, "could not create namespace") 76 tc.namespaceIDs = append(tc.namespaceIDs, "NamespaceB") 77 78 run := func(jobspec, ns string) string { 79 jobID := "test-namespace-" + uuid.Generate()[0:8] 80 f.NoError(e2e.Register(jobID, jobspec)) 81 tc.namespacedJobIDs = append(tc.namespacedJobIDs, [2]string{ns, jobID}) 82 expected := []string{"running"} 83 f.NoError(e2e.WaitForAllocStatusExpected(jobID, ns, expected), "job should be running") 84 return jobID 85 } 86 87 jobA := run("namespaces/input/namespace_a.nomad", "NamespaceA") 88 jobB := run("namespaces/input/namespace_b.nomad", "NamespaceB") 89 jobDefault := run("namespaces/input/namespace_default.nomad", "") 90 91 // exercise 'nomad job status' filtering 92 parse := func(out string) []map[string]string { 93 rows, err := e2e.ParseColumns(out) 94 f.NoError(err, "failed to parse job status output: %v", out) 95 96 result := make([]map[string]string, 0, len(rows)) 97 for _, row := range rows { 98 jobID := row["Job ID"] 99 if jobID == "" { 100 jobID = row["ID"] 101 } 102 if strings.HasPrefix(jobID, "test-namespace-") { 103 result = append(result, row) 104 } 105 } 106 return result 107 } 108 109 out, err := e2e.Command("nomad", "job", "status", "-namespace", "NamespaceA") 110 f.NoError(err, "'nomad job status -namespace NamespaceA' failed") 111 rows := parse(out) 112 f.Len(rows, 1) 113 f.Equal(jobA, rows[0]["ID"]) 114 115 out, err = e2e.Command("nomad", "job", "status", "-namespace", "NamespaceB") 116 f.NoError(err, "'nomad job status -namespace NamespaceB' failed") 117 rows = parse(out) 118 f.Len(rows, 1) 119 f.Equal(jobB, rows[0]["ID"]) 120 121 out, err = e2e.Command("nomad", "job", "status", "-namespace", "*") 122 f.NoError(err, "'nomad job status -namespace *' failed") 123 rows = parse(out) 124 f.Equal(3, len(rows)) 125 126 out, err = e2e.Command("nomad", "job", "status") 127 f.NoError(err, "'nomad job status' failed") 128 rows = parse(out) 129 f.Len(rows, 1) 130 f.Equal(jobDefault, rows[0]["ID"]) 131 132 // exercise 'nomad status' filtering 133 134 out, err = e2e.Command("nomad", "status", "-namespace", "NamespaceA") 135 f.NoError(err, "'nomad job status -namespace NamespaceA' failed") 136 rows = parse(out) 137 f.Len(rows, 1) 138 f.Equal(jobA, rows[0]["ID"]) 139 140 out, err = e2e.Command("nomad", "status", "-namespace", "NamespaceB") 141 f.NoError(err, "'nomad job status -namespace NamespaceB' failed") 142 rows = parse(out) 143 f.Len(rows, 1) 144 f.Equal(jobB, rows[0]["ID"]) 145 146 out, err = e2e.Command("nomad", "status", "-namespace", "*") 147 f.NoError(err, "'nomad job status -namespace *' failed") 148 rows = parse(out) 149 f.Equal(3, len(rows)) 150 151 out, err = e2e.Command("nomad", "status") 152 f.NoError(err, "'nomad status' failed") 153 rows = parse(out) 154 f.Len(rows, 1) 155 f.Equal(jobDefault, rows[0]["ID"]) 156 157 // exercise 'nomad deployment list' filtering 158 // note: '-namespace *' is only supported for job and alloc subcommands 159 160 out, err = e2e.Command("nomad", "deployment", "list", "-namespace", "NamespaceA") 161 f.NoError(err, "'nomad job status -namespace NamespaceA' failed") 162 rows = parse(out) 163 f.Len(rows, 1) 164 f.Equal(jobA, rows[0]["Job ID"]) 165 166 out, err = e2e.Command("nomad", "deployment", "list", "-namespace", "NamespaceB") 167 f.NoError(err, "'nomad job status -namespace NamespaceB' failed") 168 rows = parse(out) 169 f.Equal(len(rows), 1) 170 f.Equal(jobB, rows[0]["Job ID"]) 171 172 out, err = e2e.Command("nomad", "deployment", "list") 173 f.NoError(err, "'nomad deployment list' failed") 174 rows = parse(out) 175 f.Len(rows, 1) 176 f.Equal(jobDefault, rows[0]["Job ID"]) 177 178 out, err = e2e.Command("nomad", "job", "stop", jobA) 179 f.Equal(fmt.Sprintf("No job(s) with prefix or id %q found\n", jobA), out) 180 f.Error(err, "exit status 1") 181 182 _, err = e2e.Command("nomad", "job", "stop", "-namespace", "NamespaceA", jobA) 183 f.NoError(err, "could not stop job in namespace") 184 }