Merge pull request #17940 from soltysh/job_deadline

Added ActiveDeadlineSeconds to jobs
This commit is contained in:
Eric Tune
2015-12-17 13:11:13 -08:00
21 changed files with 16070 additions and 14806 deletions

View File

@@ -1383,6 +1383,12 @@ func deepCopy_extensions_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner)
} else {
out.Completions = nil
}
if in.ActiveDeadlineSeconds != nil {
out.ActiveDeadlineSeconds = new(int64)
*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
} else {
out.ActiveDeadlineSeconds = nil
}
if in.Selector != nil {
out.Selector = new(LabelSelector)
if err := deepCopy_extensions_LabelSelector(*in.Selector, out.Selector, c); err != nil {

File diff suppressed because it is too large Load Diff

View File

@@ -410,6 +410,10 @@ type JobSpec struct {
// job should be run with. Defaults to 1.
Completions *int `json:"completions,omitempty"`
// Optional duration in seconds relative to the startTime that the job may be active
// before the system tries to terminate it; value must be positive integer
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
// Selector is a label query over pods that should match the pod count.
Selector *LabelSelector `json:"selector,omitempty"`
@@ -450,6 +454,8 @@ type JobConditionType string
const (
// JobComplete means the job has completed its execution.
JobComplete JobConditionType = "Complete"
// JobFailed means the job has failed its execution.
JobFailed JobConditionType = "Failed"
)
// JobCondition describes current state of a job.

View File

@@ -2902,6 +2902,12 @@ func autoconvert_extensions_JobSpec_To_v1beta1_JobSpec(in *extensions.JobSpec, o
} else {
out.Completions = nil
}
if in.ActiveDeadlineSeconds != nil {
out.ActiveDeadlineSeconds = new(int64)
*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
} else {
out.ActiveDeadlineSeconds = nil
}
if in.Selector != nil {
out.Selector = new(LabelSelector)
if err := convert_extensions_LabelSelector_To_v1beta1_LabelSelector(in.Selector, out.Selector, s); err != nil {
@@ -3921,6 +3927,12 @@ func autoconvert_v1beta1_JobSpec_To_extensions_JobSpec(in *JobSpec, out *extensi
} else {
out.Completions = nil
}
if in.ActiveDeadlineSeconds != nil {
out.ActiveDeadlineSeconds = new(int64)
*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
} else {
out.ActiveDeadlineSeconds = nil
}
if in.Selector != nil {
out.Selector = new(extensions.LabelSelector)
if err := convert_v1beta1_LabelSelector_To_extensions_LabelSelector(in.Selector, out.Selector, s); err != nil {

View File

@@ -1395,6 +1395,12 @@ func deepCopy_v1beta1_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) er
} else {
out.Completions = nil
}
if in.ActiveDeadlineSeconds != nil {
out.ActiveDeadlineSeconds = new(int64)
*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
} else {
out.ActiveDeadlineSeconds = nil
}
if in.Selector != nil {
out.Selector = new(LabelSelector)
if err := deepCopy_v1beta1_LabelSelector(*in.Selector, out.Selector, c); err != nil {

File diff suppressed because it is too large Load Diff

View File

@@ -415,6 +415,10 @@ type JobSpec struct {
// More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md
Completions *int32 `json:"completions,omitempty"`
// Optional duration in seconds relative to the startTime that the job may be active
// before the system tries to terminate it; value must be positive integer
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
// Selector is a label query over pods that should match the pod count.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
Selector *LabelSelector `json:"selector,omitempty"`
@@ -458,6 +462,8 @@ type JobConditionType string
const (
// JobComplete means the job has completed its execution.
JobComplete JobConditionType = "Complete"
// JobFailed means the job has failed its execution.
JobFailed JobConditionType = "Failed"
)
// JobCondition describes current state of a job.

View File

@@ -368,11 +368,12 @@ func (JobList) SwaggerDoc() map[string]string {
}
var map_JobSpec = map[string]string{
"": "JobSpec describes how the job execution will look like.",
"parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md",
"completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Defaults to 1. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md",
"selector": "Selector is a label query over pods that should match the pod count. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors",
"template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md",
"": "JobSpec describes how the job execution will look like.",
"parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md",
"completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Defaults to 1. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md",
"activeDeadlineSeconds": "Optional duration in seconds relative to the startTime that the job may be active before the system tries to terminate it; value must be positive integer",
"selector": "Selector is a label query over pods that should match the pod count. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors",
"template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md",
}
func (JobSpec) SwaggerDoc() map[string]string {

View File

@@ -338,6 +338,9 @@ func ValidateJobSpec(spec *extensions.JobSpec, fldPath *field.Path) field.ErrorL
if spec.Completions != nil {
allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(*spec.Completions), fldPath.Child("completions"))...)
}
if spec.ActiveDeadlineSeconds != nil {
allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(*spec.ActiveDeadlineSeconds), fldPath.Child("activeDeadlineSeconds"))...)
}
if spec.Selector == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("selector")))
} else {

View File

@@ -839,6 +839,7 @@ func TestValidateJob(t *testing.T) {
}
}
negative := -1
negative64 := int64(-1)
errorCases := map[string]extensions.Job{
"spec.parallelism:must be non-negative": {
ObjectMeta: api.ObjectMeta{
@@ -862,6 +863,17 @@ func TestValidateJob(t *testing.T) {
Template: validPodTemplateSpec,
},
},
"spec.activeDeadlineSeconds:must be non-negative": {
ObjectMeta: api.ObjectMeta{
Name: "myjob",
Namespace: api.NamespaceDefault,
},
Spec: extensions.JobSpec{
ActiveDeadlineSeconds: &negative64,
Selector: validSelector,
Template: validPodTemplateSpec,
},
},
"spec.selector:required value": {
ObjectMeta: api.ObjectMeta{
Name: "myjob",

File diff suppressed because it is too large Load Diff

View File

@@ -64,6 +64,8 @@ type JobController struct {
// Jobs that need to be updated
queue *workqueue.Type
recorder record.EventRecorder
}
func NewJobController(kubeClient client.Interface, resyncPeriod controller.ResyncPeriodFunc) *JobController {
@@ -75,10 +77,11 @@ func NewJobController(kubeClient client.Interface, resyncPeriod controller.Resyn
kubeClient: kubeClient,
podControl: controller.RealPodControl{
KubeClient: kubeClient,
Recorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "job"}),
Recorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "job-controller"}),
},
expectations: controller.NewControllerExpectations(),
queue: workqueue.New(),
recorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "job-controller"}),
}
jm.jobStore.Store, jm.jobController = framework.NewInformer(
@@ -322,16 +325,52 @@ func (jm *JobController) syncJob(key string) error {
activePods := controller.FilterActivePods(podList.Items)
active := len(activePods)
succeeded, failed := getStatus(podList.Items)
if jobNeedsSync {
active = jm.manageJob(activePods, succeeded, &job)
conditions := len(job.Status.Conditions)
if job.Status.StartTime == nil {
now := unversioned.Now()
job.Status.StartTime = &now
}
completions := succeeded
if completions == *job.Spec.Completions {
job.Status.Conditions = append(job.Status.Conditions, newCondition())
if pastActiveDeadline(&job) {
// if job was finished previously, we don't want to redo the termination
if isJobFinished(&job) {
return nil
}
// TODO: below code should be replaced with pod termination resulting in
// pod failures, rather than killing pods. Unfortunately none such solution
// exists ATM. There's an open discussion in the topic in
// https://github.com/kubernetes/kubernetes/issues/14602 which might give
// some sort of solution to above problem.
// kill remaining active pods
wait := sync.WaitGroup{}
wait.Add(active)
for i := 0; i < active; i++ {
go func(ix int) {
defer wait.Done()
if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name); err != nil {
defer util.HandleError(err)
}
}(i)
}
wait.Wait()
// update status values accordingly
failed += active
active = 0
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline"))
jm.recorder.Event(&job, api.EventTypeNormal, "DeadlineExceeded", "Job was active longer than specified deadline")
} else {
if jobNeedsSync {
active = jm.manageJob(activePods, succeeded, &job)
}
completions := succeeded
if completions == *job.Spec.Completions {
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobComplete, "", ""))
now := unversioned.Now()
job.Status.CompletionTime = &now
}
}
// no need to update the job if the status hasn't changed since last time
if job.Status.Active != active || job.Status.Succeeded != succeeded || job.Status.Failed != failed {
if job.Status.Active != active || job.Status.Succeeded != succeeded || job.Status.Failed != failed || len(job.Status.Conditions) != conditions {
job.Status.Active = active
job.Status.Succeeded = succeeded
job.Status.Failed = failed
@@ -344,21 +383,38 @@ func (jm *JobController) syncJob(key string) error {
return nil
}
func newCondition() extensions.JobCondition {
// pastActiveDeadline checks if job has ActiveDeadlineSeconds field set and if it is exceeded.
func pastActiveDeadline(job *extensions.Job) bool {
if job.Spec.ActiveDeadlineSeconds == nil || job.Status.StartTime == nil {
return false
}
now := unversioned.Now()
start := job.Status.StartTime.Time
duration := now.Time.Sub(start)
allowedDuration := time.Duration(*job.Spec.ActiveDeadlineSeconds) * time.Second
return duration >= allowedDuration
}
func newCondition(conditionType extensions.JobConditionType, reason, message string) extensions.JobCondition {
return extensions.JobCondition{
Type: extensions.JobComplete,
Type: conditionType,
Status: api.ConditionTrue,
LastProbeTime: unversioned.Now(),
LastTransitionTime: unversioned.Now(),
Reason: reason,
Message: message,
}
}
// getStatus returns no of succeeded and failed pods running a job
func getStatus(pods []api.Pod) (succeeded, failed int) {
succeeded = filterPods(pods, api.PodSucceeded)
failed = filterPods(pods, api.PodFailed)
return
}
// manageJob is the core method responsible for managing the number of running
// pods according to what is specified in the job.Spec.
func (jm *JobController) manageJob(activePods []*api.Pod, succeeded int, job *extensions.Job) int {
var activeLock sync.Mutex
active := len(activePods)
@@ -447,7 +503,7 @@ func filterPods(pods []api.Pod, phase api.PodPhase) int {
func isJobFinished(j *extensions.Job) bool {
for _, c := range j.Status.Conditions {
if c.Type == extensions.JobComplete && c.Status == api.ConditionTrue {
if (c.Type == extensions.JobComplete || c.Type == extensions.JobFailed) && c.Status == api.ConditionTrue {
return true
}
}

View File

@@ -23,6 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
@@ -209,22 +210,158 @@ func TestControllerSyncJob(t *testing.T) {
if actual.Status.Failed != tc.expectedFailed {
t.Errorf("%s: unexpected number of failed pods. Expected %d, saw %d\n", name, tc.expectedFailed, actual.Status.Failed)
}
if actual.Status.StartTime == nil {
t.Errorf("%s: .status.startTime was not set", name)
}
// validate conditions
if tc.expectedComplete {
completed := false
for _, v := range actual.Status.Conditions {
if v.Type == extensions.JobComplete && v.Status == api.ConditionTrue {
completed = true
break
}
}
if !completed {
t.Errorf("%s: expected completion condition. Got %v", name, actual.Status.Conditions)
}
if tc.expectedComplete && !getCondition(actual, extensions.JobComplete) {
t.Errorf("%s: expected completion condition. Got %#v", name, actual.Status.Conditions)
}
}
}
func TestSyncJobPastDeadline(t *testing.T) {
testCases := map[string]struct {
// job setup
parallelism int
completions int
activeDeadlineSeconds int64
startTime int64
// pod setup
activePods int
succeededPods int
failedPods int
// expectations
expectedDeletions int
expectedActive int
expectedSucceeded int
expectedFailed int
}{
"activeDeadlineSeconds less than single pod execution": {
1, 1, 10, 15,
1, 0, 0,
1, 0, 0, 1,
},
"activeDeadlineSeconds bigger than single pod execution": {
1, 2, 10, 15,
1, 1, 0,
1, 0, 1, 1,
},
"activeDeadlineSeconds times-out before any pod starts": {
1, 1, 10, 10,
0, 0, 0,
0, 0, 0, 0,
},
}
for name, tc := range testCases {
// job manager setup
client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()})
manager := NewJobController(client, controller.NoResyncPeriodFunc)
fakePodControl := controller.FakePodControl{}
manager.podControl = &fakePodControl
manager.podStoreSynced = alwaysReady
var actual *extensions.Job
manager.updateHandler = func(job *extensions.Job) error {
actual = job
return nil
}
// job & pods setup
job := newJob(tc.parallelism, tc.completions)
job.Spec.ActiveDeadlineSeconds = &tc.activeDeadlineSeconds
start := unversioned.Unix(unversioned.Now().Time.Unix()-tc.startTime, 0)
job.Status.StartTime = &start
manager.jobStore.Store.Add(job)
for _, pod := range newPodList(tc.activePods, api.PodRunning, job) {
manager.podStore.Store.Add(&pod)
}
for _, pod := range newPodList(tc.succeededPods, api.PodSucceeded, job) {
manager.podStore.Store.Add(&pod)
}
for _, pod := range newPodList(tc.failedPods, api.PodFailed, job) {
manager.podStore.Store.Add(&pod)
}
// run
err := manager.syncJob(getKey(job, t))
if err != nil {
t.Errorf("%s: unexpected error when syncing jobs %v", err)
}
// validate created/deleted pods
if len(fakePodControl.Templates) != 0 {
t.Errorf("%s: unexpected number of creates. Expected 0, saw %d\n", name, len(fakePodControl.Templates))
}
if len(fakePodControl.DeletePodName) != tc.expectedDeletions {
t.Errorf("%s: unexpected number of deletes. Expected %d, saw %d\n", name, tc.expectedDeletions, len(fakePodControl.DeletePodName))
}
// validate status
if actual.Status.Active != tc.expectedActive {
t.Errorf("%s: unexpected number of active pods. Expected %d, saw %d\n", name, tc.expectedActive, actual.Status.Active)
}
if actual.Status.Succeeded != tc.expectedSucceeded {
t.Errorf("%s: unexpected number of succeeded pods. Expected %d, saw %d\n", name, tc.expectedSucceeded, actual.Status.Succeeded)
}
if actual.Status.Failed != tc.expectedFailed {
t.Errorf("%s: unexpected number of failed pods. Expected %d, saw %d\n", name, tc.expectedFailed, actual.Status.Failed)
}
if actual.Status.StartTime == nil {
t.Errorf("%s: .status.startTime was not set", name)
}
// validate conditions
if !getCondition(actual, extensions.JobFailed) {
t.Errorf("%s: expected fail condition. Got %#v", name, actual.Status.Conditions)
}
}
}
func getCondition(job *extensions.Job, condition extensions.JobConditionType) bool {
for _, v := range job.Status.Conditions {
if v.Type == condition && v.Status == api.ConditionTrue {
return true
}
}
return false
}
func TestSyncPastDeadlineJobFinished(t *testing.T) {
client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()})
manager := NewJobController(client, controller.NoResyncPeriodFunc)
fakePodControl := controller.FakePodControl{}
manager.podControl = &fakePodControl
manager.podStoreSynced = alwaysReady
var actual *extensions.Job
manager.updateHandler = func(job *extensions.Job) error {
actual = job
return nil
}
job := newJob(1, 1)
activeDeadlineSeconds := int64(10)
job.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
start := unversioned.Unix(unversioned.Now().Time.Unix()-15, 0)
job.Status.StartTime = &start
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline"))
manager.jobStore.Store.Add(job)
err := manager.syncJob(getKey(job, t))
if err != nil {
t.Errorf("Unexpected error when syncing jobs %v", err)
}
if len(fakePodControl.Templates) != 0 {
t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", 0, len(fakePodControl.Templates))
}
if len(fakePodControl.DeletePodName) != 0 {
t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", 0, len(fakePodControl.DeletePodName))
}
if actual != nil {
t.Error("Unexpected job modification")
}
}
func TestSyncJobDeleted(t *testing.T) {
client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()})
manager := NewJobController(client, controller.NoResyncPeriodFunc)

View File

@@ -895,6 +895,12 @@ func describeJob(job *extensions.Job, events *api.EventList) (string, error) {
fmt.Fprintf(out, "Selector:\t%s\n", selector)
fmt.Fprintf(out, "Parallelism:\t%d\n", *job.Spec.Parallelism)
fmt.Fprintf(out, "Completions:\t%d\n", *job.Spec.Completions)
if job.Status.StartTime != nil {
fmt.Fprintf(out, "Start Time:\t%s\n", job.Status.StartTime.Time.Format(time.RFC1123Z))
}
if job.Spec.ActiveDeadlineSeconds != nil {
fmt.Fprintf(out, "Active Deadline Seconds:\t%ds\n", *job.Spec.ActiveDeadlineSeconds)
}
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(job.Labels))
fmt.Fprintf(out, "Pods Statuses:\t%d Running / %d Succeeded / %d Failed\n", job.Status.Active, job.Status.Succeeded, job.Status.Failed)
describeVolumes(job.Spec.Template.Spec.Volumes, out)

View File

@@ -158,7 +158,13 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
yy10 := &x.ObjectMeta
yy10.CodecEncodeSelf(e)
yym11 := z.EncBinary()
_ = yym11
if false {
} else if z.HasExtensions() && z.EncExt(yy10) {
} else {
z.EncFallback(yy10)
}
} else {
r.EncodeNil()
}
@@ -167,14 +173,20 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("metadata"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy11 := &x.ObjectMeta
yy11.CodecEncodeSelf(e)
yy12 := &x.ObjectMeta
yym13 := z.EncBinary()
_ = yym13
if false {
} else if z.HasExtensions() && z.EncExt(yy12) {
} else {
z.EncFallback(yy12)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym13 := z.EncBinary()
_ = yym13
yym15 := z.EncBinary()
_ = yym15
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Key))
@@ -183,8 +195,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("Key"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym14 := z.EncBinary()
_ = yym14
yym16 := z.EncBinary()
_ = yym16
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Key))
@@ -195,8 +207,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
if x.Map == nil {
r.EncodeNil()
} else {
yym16 := z.EncBinary()
_ = yym16
yym18 := z.EncBinary()
_ = yym18
if false {
} else {
z.F.EncMapStringIntV(x.Map, false, e)
@@ -209,8 +221,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
if x.Map == nil {
r.EncodeNil()
} else {
yym17 := z.EncBinary()
_ = yym17
yym19 := z.EncBinary()
_ = yym19
if false {
} else {
z.F.EncMapStringIntV(x.Map, false, e)
@@ -222,8 +234,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
if x.StringList == nil {
r.EncodeNil()
} else {
yym19 := z.EncBinary()
_ = yym19
yym21 := z.EncBinary()
_ = yym21
if false {
} else {
z.F.EncSliceStringV(x.StringList, false, e)
@@ -236,8 +248,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
if x.StringList == nil {
r.EncodeNil()
} else {
yym20 := z.EncBinary()
_ = yym20
yym22 := z.EncBinary()
_ = yym22
if false {
} else {
z.F.EncSliceStringV(x.StringList, false, e)
@@ -249,8 +261,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
if x.IntList == nil {
r.EncodeNil()
} else {
yym22 := z.EncBinary()
_ = yym22
yym24 := z.EncBinary()
_ = yym24
if false {
} else {
z.F.EncSliceIntV(x.IntList, false, e)
@@ -263,8 +275,8 @@ func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
if x.IntList == nil {
r.EncodeNil()
} else {
yym23 := z.EncBinary()
_ = yym23
yym25 := z.EncBinary()
_ = yym25
if false {
} else {
z.F.EncSliceIntV(x.IntList, false, e)
@@ -284,25 +296,25 @@ func (x *TestStruct) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym24 := z.DecBinary()
_ = yym24
yym26 := z.DecBinary()
_ = yym26
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct25 := r.ContainerType()
if yyct25 == codecSelferValueTypeMap1234 {
yyl25 := r.ReadMapStart()
if yyl25 == 0 {
yyct27 := r.ContainerType()
if yyct27 == codecSelferValueTypeMap1234 {
yyl27 := r.ReadMapStart()
if yyl27 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl25, d)
x.codecDecodeSelfFromMap(yyl27, d)
}
} else if yyct25 == codecSelferValueTypeArray1234 {
yyl25 := r.ReadArrayStart()
if yyl25 == 0 {
} else if yyct27 == codecSelferValueTypeArray1234 {
yyl27 := r.ReadArrayStart()
if yyl27 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl25, d)
x.codecDecodeSelfFromArray(yyl27, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
@@ -314,12 +326,12 @@ func (x *TestStruct) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys26Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys26Slc
var yyhl26 bool = l >= 0
for yyj26 := 0; ; yyj26++ {
if yyhl26 {
if yyj26 >= l {
var yys28Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys28Slc
var yyhl28 bool = l >= 0
for yyj28 := 0; ; yyj28++ {
if yyhl28 {
if yyj28 >= l {
break
}
} else {
@@ -328,10 +340,10 @@ func (x *TestStruct) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys26Slc = r.DecodeBytes(yys26Slc, true, true)
yys26 := string(yys26Slc)
yys28Slc = r.DecodeBytes(yys28Slc, true, true)
yys28 := string(yys28Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys26 {
switch yys28 {
case "kind":
if r.TryDecodeAsNil() {
x.Kind = ""
@@ -348,8 +360,14 @@ func (x *TestStruct) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv29 := &x.ObjectMeta
yyv29.CodecDecodeSelf(d)
yyv31 := &x.ObjectMeta
yym32 := z.DecBinary()
_ = yym32
if false {
} else if z.HasExtensions() && z.DecExt(yyv31) {
} else {
z.DecFallback(yyv31, false)
}
}
case "Key":
if r.TryDecodeAsNil() {
@@ -361,42 +379,42 @@ func (x *TestStruct) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.Map = nil
} else {
yyv31 := &x.Map
yym32 := z.DecBinary()
_ = yym32
yyv34 := &x.Map
yym35 := z.DecBinary()
_ = yym35
if false {
} else {
z.F.DecMapStringIntX(yyv31, false, d)
z.F.DecMapStringIntX(yyv34, false, d)
}
}
case "StringList":
if r.TryDecodeAsNil() {
x.StringList = nil
} else {
yyv33 := &x.StringList
yym34 := z.DecBinary()
_ = yym34
yyv36 := &x.StringList
yym37 := z.DecBinary()
_ = yym37
if false {
} else {
z.F.DecSliceStringX(yyv33, false, d)
z.F.DecSliceStringX(yyv36, false, d)
}
}
case "IntList":
if r.TryDecodeAsNil() {
x.IntList = nil
} else {
yyv35 := &x.IntList
yym36 := z.DecBinary()
_ = yym36
yyv38 := &x.IntList
yym39 := z.DecBinary()
_ = yym39
if false {
} else {
z.F.DecSliceIntX(yyv35, false, d)
z.F.DecSliceIntX(yyv38, false, d)
}
}
default:
z.DecStructFieldNotFound(-1, yys26)
} // end switch yys26
} // end for yyj26
z.DecStructFieldNotFound(-1, yys28)
} // end switch yys28
} // end for yyj28
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
@@ -404,16 +422,16 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj37 int
var yyb37 bool
var yyhl37 bool = l >= 0
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
var yyj40 int
var yyb40 bool
var yyhl40 bool = l >= 0
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -423,13 +441,13 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
} else {
x.Kind = string(r.DecodeString())
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -439,13 +457,13 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
} else {
x.APIVersion = string(r.DecodeString())
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -453,16 +471,22 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv40 := &x.ObjectMeta
yyv40.CodecDecodeSelf(d)
yyv43 := &x.ObjectMeta
yym44 := z.DecBinary()
_ = yym44
if false {
} else if z.HasExtensions() && z.DecExt(yyv43) {
} else {
z.DecFallback(yyv43, false)
}
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -472,13 +496,13 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
} else {
x.Key = string(r.DecodeString())
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -486,21 +510,21 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.Map = nil
} else {
yyv42 := &x.Map
yym43 := z.DecBinary()
_ = yym43
yyv46 := &x.Map
yym47 := z.DecBinary()
_ = yym47
if false {
} else {
z.F.DecMapStringIntX(yyv42, false, d)
z.F.DecMapStringIntX(yyv46, false, d)
}
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -508,21 +532,21 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.StringList = nil
} else {
yyv44 := &x.StringList
yym45 := z.DecBinary()
_ = yym45
yyv48 := &x.StringList
yym49 := z.DecBinary()
_ = yym49
if false {
} else {
z.F.DecSliceStringX(yyv44, false, d)
z.F.DecSliceStringX(yyv48, false, d)
}
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -530,26 +554,26 @@ func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.IntList = nil
} else {
yyv46 := &x.IntList
yym47 := z.DecBinary()
_ = yym47
yyv50 := &x.IntList
yym51 := z.DecBinary()
_ = yym51
if false {
} else {
z.F.DecSliceIntX(yyv46, false, d)
z.F.DecSliceIntX(yyv50, false, d)
}
}
for {
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
yyj40++
if yyhl40 {
yyb40 = yyj40 > l
} else {
yyb37 = r.CheckBreak()
yyb40 = r.CheckBreak()
}
if yyb37 {
if yyb40 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj37-1, "")
z.DecStructFieldNotFound(yyj40-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}

View File

@@ -156,18 +156,30 @@ func (x *TestResource) CodecEncodeSelf(e *codec1978.Encoder) {
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yy10 := &x.ObjectMeta
yy10.CodecEncodeSelf(e)
yym11 := z.EncBinary()
_ = yym11
if false {
} else if z.HasExtensions() && z.EncExt(yy10) {
} else {
z.EncFallback(yy10)
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("metadata"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy11 := &x.ObjectMeta
yy11.CodecEncodeSelf(e)
yy12 := &x.ObjectMeta
yym13 := z.EncBinary()
_ = yym13
if false {
} else if z.HasExtensions() && z.EncExt(yy12) {
} else {
z.EncFallback(yy12)
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym13 := z.EncBinary()
_ = yym13
yym15 := z.EncBinary()
_ = yym15
if false {
} else {
r.EncodeInt(int64(x.Value))
@@ -176,8 +188,8 @@ func (x *TestResource) CodecEncodeSelf(e *codec1978.Encoder) {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("value"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym14 := z.EncBinary()
_ = yym14
yym16 := z.EncBinary()
_ = yym16
if false {
} else {
r.EncodeInt(int64(x.Value))
@@ -196,25 +208,25 @@ func (x *TestResource) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym15 := z.DecBinary()
_ = yym15
yym17 := z.DecBinary()
_ = yym17
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct16 := r.ContainerType()
if yyct16 == codecSelferValueTypeMap1234 {
yyl16 := r.ReadMapStart()
if yyl16 == 0 {
yyct18 := r.ContainerType()
if yyct18 == codecSelferValueTypeMap1234 {
yyl18 := r.ReadMapStart()
if yyl18 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl16, d)
x.codecDecodeSelfFromMap(yyl18, d)
}
} else if yyct16 == codecSelferValueTypeArray1234 {
yyl16 := r.ReadArrayStart()
if yyl16 == 0 {
} else if yyct18 == codecSelferValueTypeArray1234 {
yyl18 := r.ReadArrayStart()
if yyl18 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl16, d)
x.codecDecodeSelfFromArray(yyl18, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
@@ -226,12 +238,12 @@ func (x *TestResource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys17Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys17Slc
var yyhl17 bool = l >= 0
for yyj17 := 0; ; yyj17++ {
if yyhl17 {
if yyj17 >= l {
var yys19Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys19Slc
var yyhl19 bool = l >= 0
for yyj19 := 0; ; yyj19++ {
if yyhl19 {
if yyj19 >= l {
break
}
} else {
@@ -240,10 +252,10 @@ func (x *TestResource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys17Slc = r.DecodeBytes(yys17Slc, true, true)
yys17 := string(yys17Slc)
yys19Slc = r.DecodeBytes(yys19Slc, true, true)
yys19 := string(yys19Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys17 {
switch yys19 {
case "kind":
if r.TryDecodeAsNil() {
x.Kind = ""
@@ -260,8 +272,14 @@ func (x *TestResource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv20 := &x.ObjectMeta
yyv20.CodecDecodeSelf(d)
yyv22 := &x.ObjectMeta
yym23 := z.DecBinary()
_ = yym23
if false {
} else if z.HasExtensions() && z.DecExt(yyv22) {
} else {
z.DecFallback(yyv22, false)
}
}
case "value":
if r.TryDecodeAsNil() {
@@ -270,9 +288,9 @@ func (x *TestResource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
x.Value = int(r.DecodeInt(codecSelferBitsize1234))
}
default:
z.DecStructFieldNotFound(-1, yys17)
} // end switch yys17
} // end for yyj17
z.DecStructFieldNotFound(-1, yys19)
} // end switch yys19
} // end for yyj19
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
@@ -280,16 +298,16 @@ func (x *TestResource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj22 int
var yyb22 bool
var yyhl22 bool = l >= 0
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
var yyj25 int
var yyb25 bool
var yyhl25 bool = l >= 0
yyj25++
if yyhl25 {
yyb25 = yyj25 > l
} else {
yyb22 = r.CheckBreak()
yyb25 = r.CheckBreak()
}
if yyb22 {
if yyb25 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -299,13 +317,13 @@ func (x *TestResource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
} else {
x.Kind = string(r.DecodeString())
}
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
yyj25++
if yyhl25 {
yyb25 = yyj25 > l
} else {
yyb22 = r.CheckBreak()
yyb25 = r.CheckBreak()
}
if yyb22 {
if yyb25 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -315,13 +333,13 @@ func (x *TestResource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
} else {
x.APIVersion = string(r.DecodeString())
}
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
yyj25++
if yyhl25 {
yyb25 = yyj25 > l
} else {
yyb22 = r.CheckBreak()
yyb25 = r.CheckBreak()
}
if yyb22 {
if yyb25 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -329,16 +347,22 @@ func (x *TestResource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv25 := &x.ObjectMeta
yyv25.CodecDecodeSelf(d)
yyv28 := &x.ObjectMeta
yym29 := z.DecBinary()
_ = yym29
if false {
} else if z.HasExtensions() && z.DecExt(yyv28) {
} else {
z.DecFallback(yyv28, false)
}
}
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
yyj25++
if yyhl25 {
yyb25 = yyj25 > l
} else {
yyb22 = r.CheckBreak()
yyb25 = r.CheckBreak()
}
if yyb22 {
if yyb25 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -349,17 +373,17 @@ func (x *TestResource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
x.Value = int(r.DecodeInt(codecSelferBitsize1234))
}
for {
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
yyj25++
if yyhl25 {
yyb25 = yyj25 > l
} else {
yyb22 = r.CheckBreak()
yyb25 = r.CheckBreak()
}
if yyb22 {
if yyb25 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj22-1, "")
z.DecStructFieldNotFound(yyj25-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}