src/client/pkg/require/require.go
func ElementsEqualOrErr(expecteds interface{}, actuals interface{}) error {
	es := reflect.ValueOf(expecteds)
	as := reflect.ValueOf(actuals)

	// If either slice is empty, check that both are empty
	esIsEmpty := expecteds == nil || es.IsNil() || (es.Kind() == reflect.Slice && es.Len() == 0)
	asIsEmpty := actuals == nil || as.IsNil() || (as.Kind() == reflect.Slice && as.Len() == 0)
	if esIsEmpty && asIsEmpty {
		return nil
	} else if esIsEmpty {
		return fmt.Errorf("expected 0 elements, but got %d: %v", as.Len(), actuals)
	} else if asIsEmpty {
		return fmt.Errorf("expected %d elements, but got 0\n  expected: %v", es.Len(), expecteds)
	}

	// Both slices are nonempty--compare elements
	if es.Kind() != reflect.Slice {
		return fmt.Errorf("\"expecteds\" must be a slice, but was %s", es.Type().String())
	}
	if as.Kind() != reflect.Slice {
		return fmt.Errorf("\"actuals\" must be a slice, but was %s", as.Type().String())
	}

	// Make sure expecteds and actuals are slices of the same type, modulo
	// pointers (*T ~= T in this function)
	esArePtrs := es.Type().Elem().Kind() == reflect.Ptr
	asArePtrs := as.Type().Elem().Kind() == reflect.Ptr
	esElemType, asElemType := es.Type().Elem(), as.Type().Elem()
	if esArePtrs {
		esElemType = es.Type().Elem().Elem()
	}
	if asArePtrs {
		asElemType = as.Type().Elem().Elem()
	}
	if esElemType != asElemType {
		return fmt.Errorf("Expected []%s but got []%s", es.Type().Elem(), as.Type().Elem())
	}

	// Count up elements of expecteds
	intType := reflect.TypeOf(int64(0))
	expectedCt := reflect.MakeMap(reflect.MapOf(esElemType, intType))
	for i := 0; i < es.Len(); i++ {
		v := es.Index(i)
		if esArePtrs {
			v = v.Elem()
		}
		if !expectedCt.MapIndex(v).IsValid() {
			expectedCt.SetMapIndex(v, reflect.ValueOf(int64(1)))
		} else {
			newCt := expectedCt.MapIndex(v).Int() + 1
			expectedCt.SetMapIndex(v, reflect.ValueOf(newCt))
		}
	}

	// Count up elements of actuals
	actualCt := reflect.MakeMap(reflect.MapOf(asElemType, intType))
	for i := 0; i < as.Len(); i++ {
		v := as.Index(i)
		if asArePtrs {
			v = v.Elem()
		}
		if !actualCt.MapIndex(v).IsValid() {
			actualCt.SetMapIndex(v, reflect.ValueOf(int64(1)))
		} else {
			newCt := actualCt.MapIndex(v).Int() + 1
			actualCt.SetMapIndex(v, reflect.ValueOf(newCt))
		}
	}
	if expectedCt.Len() != actualCt.Len() {
		// slight abuse of error: contains newlines so final output prints well
		return fmt.Errorf("expected %d distinct elements, but got %d\n  expected: %v\n  actual: %v", expectedCt.Len(), actualCt.Len(), expecteds, actuals)
	}
	for _, key := range expectedCt.MapKeys() {
		ec := expectedCt.MapIndex(key)
		ac := actualCt.MapIndex(key)
		if !ec.IsValid() || !ac.IsValid() || ec.Int() != ac.Int() {
			ecInt, acInt := int64(0), int64(0)
			if ec.IsValid() {
				ecInt = ec.Int()
			}
			if ac.IsValid() {
				acInt = ac.Int()
			}
			// slight abuse of error: contains newlines so final output prints well
			return fmt.Errorf("expected %d copies of %v, but got %d copies\n  expected: %v\n  actual: %v", ecInt, key, acInt, expecteds, actuals)
		}
	}
	return nil
}
func ElementsEqualOrErr(expecteds interface{}, actuals interface{}) error {
	es := reflect.ValueOf(expecteds)
	as := reflect.ValueOf(actuals)

	// If either slice is empty, check that both are empty
	esIsEmpty := expecteds == nil || es.IsNil() || (es.Kind() == reflect.Slice && es.Len() == 0)
	asIsEmpty := actuals == nil || as.IsNil() || (as.Kind() == reflect.Slice && as.Len() == 0)
	if esIsEmpty && asIsEmpty {
		return nil
	} else if esIsEmpty {
		return fmt.Errorf("expected 0 elements, but got %d: %v", as.Len(), actuals)
	} else if asIsEmpty {
		return fmt.Errorf("expected %d elements, but got 0\n  expected: %v", es.Len(), expecteds)
	}

	// Both slices are nonempty--compare elements
	if es.Kind() != reflect.Slice {
		return fmt.Errorf("\"expecteds\" must be a slice, but was %s", es.Type().String())
	}
	if as.Kind() != reflect.Slice {
		return fmt.Errorf("\"actuals\" must be a slice, but was %s", as.Type().String())
	}

	// Make sure expecteds and actuals are slices of the same type, modulo
	// pointers (*T ~= T in this function)
	esArePtrs := es.Type().Elem().Kind() == reflect.Ptr
	asArePtrs := as.Type().Elem().Kind() == reflect.Ptr
	esElemType, asElemType := es.Type().Elem(), as.Type().Elem()
	if esArePtrs {
		esElemType = es.Type().Elem().Elem()
	}
	if asArePtrs {
		asElemType = as.Type().Elem().Elem()
	}
	if esElemType != asElemType {
		return fmt.Errorf("Expected []%s but got []%s", es.Type().Elem(), as.Type().Elem())
	}

	// Count up elements of expecteds
	intType := reflect.TypeOf(int64(0))
	expectedCt := reflect.MakeMap(reflect.MapOf(esElemType, intType))
	for i := 0; i < es.Len(); i++ {
		v := es.Index(i)
		if esArePtrs {
			v = v.Elem()
		}
		if !expectedCt.MapIndex(v).IsValid() {
			expectedCt.SetMapIndex(v, reflect.ValueOf(int64(1)))
		} else {
			newCt := expectedCt.MapIndex(v).Int() + 1
			expectedCt.SetMapIndex(v, reflect.ValueOf(newCt))
		}
	}

	// Count up elements of actuals
	actualCt := reflect.MakeMap(reflect.MapOf(asElemType, intType))
	for i := 0; i < as.Len(); i++ {
		v := as.Index(i)
		if asArePtrs {
			v = v.Elem()
		}
		if !actualCt.MapIndex(v).IsValid() {
			actualCt.SetMapIndex(v, reflect.ValueOf(int64(1)))
		} else {
			newCt := actualCt.MapIndex(v).Int() + 1
			actualCt.SetMapIndex(v, reflect.ValueOf(newCt))
		}
	}
	if expectedCt.Len() != actualCt.Len() {
		// slight abuse of error: contains newlines so final output prints well
		return fmt.Errorf("expected %d distinct elements, but got %d\n  expected: %v\n  actual: %v", expectedCt.Len(), actualCt.Len(), expecteds, actuals)
	}
	for _, key := range expectedCt.MapKeys() {
		ec := expectedCt.MapIndex(key)
		ac := actualCt.MapIndex(key)
		if !ec.IsValid() || !ac.IsValid() || ec.Int() != ac.Int() {
			ecInt, acInt := int64(0), int64(0)
			if ec.IsValid() {
				ecInt = ec.Int()
			}
			if ac.IsValid() {
				acInt = ac.Int()
			}
			// slight abuse of error: contains newlines so final output prints well
			return fmt.Errorf("expected %d copies of %v, but got %d copies\n  expected: %v\n  actual: %v", ecInt, key, acInt, expecteds, actuals)
		}
	}
	return nil
}
// ElementsEqualOrErr returns nil if the elements of the slice "expecteds" are
// exactly the elements of the slice "actuals", ignoring order (i.e.
// setwise-equal), and an error otherwise.
//
// Unlike other require.* functions, this returns an error, so that if the
// caller is polling e.g. ListCommit or ListAdmins, they can wrap
// ElementsEqualOrErr in a retry loop.
//
// Also, like ElementsEqual, treat 'nil' and the empty slice as equivalent (for
// convenience)