Commit 74244283 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #35480 from rmmh/update_owners_local

Automatic merge from submit-queue Make hack/update_owners.py get list from local repo, add --check option. This should become a verify step soon. The munger understands the * syntax already.
parents b5d604bc 78eeb763
...@@ -14,12 +14,14 @@ ...@@ -14,12 +14,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import argparse
import collections import collections
import csv import csv
import re import re
import json import json
import os import os
import random import random
import subprocess
import sys import sys
import time import time
import urllib2 import urllib2
...@@ -33,6 +35,13 @@ SKIP_MAINTAINERS = { ...@@ -33,6 +35,13 @@ SKIP_MAINTAINERS = {
'a-robinson', 'aronchick', 'bgrant0607-nocc', 'david-mcmahon', 'a-robinson', 'aronchick', 'bgrant0607-nocc', 'david-mcmahon',
'goltermann', 'sarahnovotny'} 'goltermann', 'sarahnovotny'}
def normalize(name):
name = re.sub(r'\[.*?\]|\{.*?\}', '', name)
name = re.sub(r'\s+', ' ', name)
return name.strip()
def get_test_history(days_ago): def get_test_history(days_ago):
url = time.strftime(GCS_URL_BASE + 'logs/%Y-%m-%d.json', url = time.strftime(GCS_URL_BASE + 'logs/%Y-%m-%d.json',
time.gmtime(time.time() - days_ago * 24 * 60 * 60)) time.gmtime(time.time() - days_ago * 24 * 60 * 60))
...@@ -43,10 +52,19 @@ def get_test_history(days_ago): ...@@ -43,10 +52,19 @@ def get_test_history(days_ago):
return json.loads(content) return json.loads(content)
def normalize(name): def get_test_names_from_test_history():
name = re.sub(r'\[.*?\]|\{.*?\}', '', name) test_names = set()
name = re.sub(r'\s+', ' ', name) for days_ago in range(4):
return name.strip() test_history = get_test_history(days_ago)
test_names.update(normalize(name) for name in test_history['test_names'])
return test_names
def get_test_names_from_local_files():
tests_json = subprocess.check_output(['go', 'run', 'test/list/main.go', '-json'])
tests = json.loads(tests_json)
return {normalize(t['Name'] + (' ' + t['TestName'] if 'k8s.io/' not in t['Name'] else ''))
for t in tests}
def load_owners(fname): def load_owners(fname):
...@@ -98,10 +116,16 @@ def get_maintainers(): ...@@ -98,10 +116,16 @@ def get_maintainers():
def main(): def main():
test_names = set() parser = argparse.ArgumentParser()
for days_ago in range(4): parser.add_argument('--history', action='store_true', help='Generate test list from result history.')
test_history = get_test_history(days_ago) parser.add_argument('--user', help='User to assign new tests to (RANDOM for random assignment).')
test_names.update(normalize(name) for name in test_history['test_names']) parser.add_argument('--check', action='store_true', help='Exit with a nonzero status if the test list has changed.')
options = parser.parse_args()
if options.history:
test_names = get_test_names_from_test_history()
else:
test_names = get_test_names_from_local_files()
test_names.add('DEFAULT') test_names.add('DEFAULT')
test_names = sorted(test_names) test_names = sorted(test_names)
owners = load_owners(OWNERS_PATH) owners = load_owners(OWNERS_PATH)
...@@ -115,6 +139,13 @@ def main(): ...@@ -115,6 +139,13 @@ def main():
print '# NEW TESTS (%d):' % len(new_tests) print '# NEW TESTS (%d):' % len(new_tests)
print '\n'.join(new_tests) print '\n'.join(new_tests)
if options.check:
if new_tests or outdated_tests:
print
print 'ERROR: the test list has changed'
sys.exit(1)
sys.exit(0)
for name in outdated_tests: for name in outdated_tests:
owners.pop(name) owners.pop(name)
...@@ -130,7 +161,12 @@ def main(): ...@@ -130,7 +161,12 @@ def main():
owner for name, (owner, random) in owners.iteritems() owner for name, (owner, random) in owners.iteritems()
if owner in maintainers) if owner in maintainers)
for test_name in set(test_names) - set(owners): for test_name in set(test_names) - set(owners):
new_owner, _count = random.choice(owner_counts.most_common()[-4:]) if options.user == 'RANDOM':
new_owner, _count = random.choice(owner_counts.most_common()[-4:])
elif options.user:
new_owner = options.user
else:
raise AssertionError('--user must be specified for new tests')
owner_counts[new_owner] += 1 owner_counts[new_owner] += 1
owners[test_name] = (new_owner, True) owners[test_name] = (new_owner, True)
......
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
) )
var _ = framework.KubeDescribe("[Feature:Empty]", func() { var _ = framework.KubeDescribe("Empty [Feature:Empty]", func() {
f := framework.NewDefaultFramework("empty") f := framework.NewDefaultFramework("empty")
BeforeEach(func() { BeforeEach(func() {
...@@ -39,5 +39,5 @@ var _ = framework.KubeDescribe("[Feature:Empty]", func() { ...@@ -39,5 +39,5 @@ var _ = framework.KubeDescribe("[Feature:Empty]", func() {
framework.ExpectNoError(err) framework.ExpectNoError(err)
}) })
It("Does nothing", func() {}) It("does nothing", func() {})
}) })
...@@ -38,58 +38,50 @@ import ( ...@@ -38,58 +38,50 @@ import (
var _ = framework.KubeDescribe("AppArmor [Feature:AppArmor]", func() { var _ = framework.KubeDescribe("AppArmor [Feature:AppArmor]", func() {
if isAppArmorEnabled() { if isAppArmorEnabled() {
testAppArmorNode() BeforeEach(func() {
} else { By("Loading AppArmor profiles for testing")
testNonAppArmorNode() framework.ExpectNoError(loadTestProfiles(), "Could not load AppArmor test profiles")
}
})
func testAppArmorNode() {
BeforeEach(func() {
By("Loading AppArmor profiles for testing")
framework.ExpectNoError(loadTestProfiles(), "Could not load AppArmor test profiles")
})
Context("when running with AppArmor", func() {
f := framework.NewDefaultFramework("apparmor-test")
It("should reject an unloaded profile", func() {
status := runAppArmorTest(f, apparmor.ProfileNamePrefix+"non-existant-profile")
Expect(status.Phase).To(Equal(api.PodFailed), "PodStatus: %+v", status)
Expect(status.Reason).To(Equal("AppArmor"), "PodStatus: %+v", status)
}) })
It("should enforce a profile blocking writes", func() { Context("when running with AppArmor", func() {
status := runAppArmorTest(f, apparmor.ProfileNamePrefix+apparmorProfilePrefix+"deny-write") f := framework.NewDefaultFramework("apparmor-test")
if len(status.ContainerStatuses) == 0 {
framework.Failf("Unexpected pod status: %s", spew.Sdump(status)) It("should reject an unloaded profile", func() {
return status := runAppArmorTest(f, apparmor.ProfileNamePrefix+"non-existant-profile")
} Expect(status.Phase).To(Equal(api.PodFailed), "PodStatus: %+v", status)
state := status.ContainerStatuses[0].State.Terminated Expect(status.Reason).To(Equal("AppArmor"), "PodStatus: %+v", status)
Expect(state.ExitCode).To(Not(BeZero()), "ContainerStateTerminated: %+v", state) })
It("should enforce a profile blocking writes", func() {
}) status := runAppArmorTest(f, apparmor.ProfileNamePrefix+apparmorProfilePrefix+"deny-write")
It("should enforce a permissive profile", func() { if len(status.ContainerStatuses) == 0 {
status := runAppArmorTest(f, apparmor.ProfileNamePrefix+apparmorProfilePrefix+"audit-write") framework.Failf("Unexpected pod status: %s", spew.Sdump(status))
if len(status.ContainerStatuses) == 0 { return
framework.Failf("Unexpected pod status: %s", spew.Sdump(status)) }
return state := status.ContainerStatuses[0].State.Terminated
} Expect(state.ExitCode).To(Not(BeZero()), "ContainerStateTerminated: %+v", state)
state := status.ContainerStatuses[0].State.Terminated
Expect(state.ExitCode).To(BeZero(), "ContainerStateTerminated: %+v", state) })
It("should enforce a permissive profile", func() {
status := runAppArmorTest(f, apparmor.ProfileNamePrefix+apparmorProfilePrefix+"audit-write")
if len(status.ContainerStatuses) == 0 {
framework.Failf("Unexpected pod status: %s", spew.Sdump(status))
return
}
state := status.ContainerStatuses[0].State.Terminated
Expect(state.ExitCode).To(BeZero(), "ContainerStateTerminated: %+v", state)
})
}) })
}) } else {
} Context("when running without AppArmor", func() {
f := framework.NewDefaultFramework("apparmor-test")
func testNonAppArmorNode() {
Context("when running without AppArmor", func() { It("should reject a pod with an AppArmor profile", func() {
f := framework.NewDefaultFramework("apparmor-test") status := runAppArmorTest(f, apparmor.ProfileRuntimeDefault)
Expect(status.Phase).To(Equal(api.PodFailed), "PodStatus: %+v", status)
It("should reject a pod with an AppArmor profile", func() { Expect(status.Reason).To(Equal("AppArmor"), "PodStatus: %+v", status)
status := runAppArmorTest(f, apparmor.ProfileRuntimeDefault) })
Expect(status.Phase).To(Equal(api.PodFailed), "PodStatus: %+v", status)
Expect(status.Reason).To(Equal("AppArmor"), "PodStatus: %+v", status)
}) })
}) }
} })
const apparmorProfilePrefix = "e2e-node-apparmor-test-" const apparmorProfilePrefix = "e2e-node-apparmor-test-"
const testProfiles = ` const testProfiles = `
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment