func()

in e2etest/newe2e_task_azcopy_job_validate.go [108:240]


func (e *ExpectedPlanFile) Validate(a Asserter, header *ste.JobPartPlanHeader) {
	a.AssertNow("Expected plan file cannot be nil", Not{IsNil{}}, e)
	a.AssertNow("Header cannot be nil", Not{IsNil{}}, header)

	self := reflect.ValueOf(e).Elem()
	hVal := reflect.ValueOf(header).Elem()

	type queueItem struct {
		val  reflect.Value
		path string
	}

	appendPath := func(base, new string) string {
		if len(base) == 0 {
			return new
		}

		return base + "." + new
	}

	queue := []queueItem{{self, ""}}
	for len(queue) > 0 {
		item := queue[0]
		queue = queue[1:]
		val := item.val
		vType := val.Type()
		numFields := val.NumField()
		for i := 0; i < numFields; i++ {
			field := val.Field(i)
			tag := vType.Field(i).Tag
			name := vType.Field(i).Name

			newPath := appendPath(item.path, name)

			kind := field.Kind()
			// deref if necessary
			if kind == reflect.Pointer || kind == reflect.Interface {
				field = field.Elem()
				if !field.IsValid() {
					continue
				}

				kind = field.Kind()
			}

			tagVal, ok := tag.Lookup("validate")
			if !ok {
				// If nothing was specified, and this isn't a struct, it probably has some other processing.
				if kind == reflect.Struct {
					queue = append(queue, queueItem{field, newPath})
					continue
				}

				continue
			}

			splits := strings.Split(tagVal, ",")
			a.AssertNow("validate tag must split into exactly two sets "+newPath, Equal{}, len(splits), 2)
			tagName := splits[0]
			tagPath := strings.Split(splits[1], ".")

			target := hVal
			for n, v := range tagPath {
				target = hVal.FieldByName(v)
				kind := target.Kind()

				if kind == reflect.Pointer || kind == reflect.Interface {
					target = target.Elem()
					kind = target.Kind()
				}

				if n != len(tagPath)-1 {
					a.AssertNow(fmt.Sprintf("Element %s must be a struct %s", v, newPath), Equal{}, kind, reflect.Struct)
				}
			}

			if !field.IsNil() {
				a.Assert(
					fmt.Sprintf("Element %s must equal value to the real job plan (%v (expected) != %v (actual))", tagName, field.Interface(), target.Interface()),
					Equal{Deep: true},
					field.Interface(),
					target.Interface(),
				)
			}
		}
	}

	// validate the additional manual fields
	//header.DstBlobData.
	if e.BlobData.CacheControl != nil {
		str := string(header.DstBlobData.CacheControl[:header.DstBlobData.CacheControlLength])
		a.Assert("CacheControl differs in header", Equal{}, *e.BlobData.CacheControl, str)
	}

	if e.BlobData.ContentType != nil {
		str := string(header.DstBlobData.ContentType[:header.DstBlobData.ContentTypeLength])
		a.Assert("ContentType differs in header", Equal{}, *e.BlobData.ContentType, str)
	}

	if e.BlobData.ContentEncoding != nil {
		str := string(header.DstBlobData.ContentEncoding[:header.DstBlobData.ContentEncodingLength])
		a.Assert("ContentEncoding differs in header", Equal{}, *e.BlobData.ContentEncoding, str)
	}

	if e.BlobData.ContentLanguage != nil {
		str := string(header.DstBlobData.ContentLanguage[:header.DstBlobData.ContentLanguageLength])
		a.Assert("ContentLanguage differs in header", Equal{}, *e.BlobData.ContentLanguage, str)
	}

	if e.BlobData.ContentDisposition != nil {
		str := string(header.DstBlobData.ContentDisposition[:header.DstBlobData.ContentDispositionLength])
		a.Assert("ContentDisposition differs in header", Equal{}, *e.BlobData.ContentDisposition, str)
	}

	if e.BlobData.Metadata != nil {
		metadataStr := string(header.DstBlobData.Metadata[:header.DstBlobData.MetadataLength])
		meta, err := common.StringToMetadata(metadataStr)
		a.NoError("Parse metadata", err)

		a.Assert("Metadata differs in header", Equal{Deep: true}, e.BlobData.Metadata, meta)
	}

	if e.BlobData.BlobTags != nil {
		tagsStr := string(header.DstBlobData.BlobTags[:header.DstBlobData.BlobTagsLength])
		tags := common.ToCommonBlobTagsMap(tagsStr)
		a.Assert("Tags differ in header", Equal{Deep: true}, e.BlobData.BlobTags, tags)
	}

	if e.BlobData.CpkScopeInfo != nil {
		CpkScopeStr := string(header.DstBlobData.CpkScopeInfo[:header.DstBlobData.CpkScopeInfoLength])
		a.Assert("CPK Scope Info differs in header", Equal{Deep: true}, *e.BlobData.CpkScopeInfo, CpkScopeStr)
	}
}