Hi all, I'm trying to write a text/template callba...
# golang
Hi all, I'm trying to write a text/template callback helper... I have the following code which works with a unit test, but not if I call
pulumi up
Copy code
func Template(tmpl string, data interface{}) pulumi.StringOutput {
	any := pulumi.Any(data)
	return pulumi.All(tmpl, any).ApplyString(func(v interface{}) (string, error) {
		args := v.([]interface{})
		toParse := args[0].(string)
		fields := args[1].(interface{})
		Debug(fields, "test")
		var buf bytes.Buffer
		parsed, err := template.New("tmpl").Parse(toParse)
		if err != nil {
			return "", err

		if err := parsed.Execute(&buf, fields); err != nil {
			return "", err
		return buf.String(), nil
Copy code
func TestTemplate(t *testing.T) {
	tests := []struct {
		name string
		tmpl string
		data interface{}
		want string
			name: "Shallow object",
			tmpl: "Hello, {{ .Field }}!",
			data: struct{ Field pulumi.StringInput }{Field: pulumi.String("world")},
			want: "Hello, world!",
	for _, tt := range tests {
		var wg sync.WaitGroup
		t.Run(tt.name, func(t *testing.T) {
			got := Template(tt.tmpl, tt.data)
			pulumi.All(got, tt.want).ApplyString(func(args []interface{}) (string, error) {
				a := args[0].(string)
				b := args[1].(string)
				if diff := cmp.Diff(a, b); diff != "" {
				return "", nil
this passes ^^
But when I run this against a stack via
pulumi up
the fields get populated with the memory addresses.
I wonder if its because my tests use a
based input whereas my
pulumi up
loads it in from config.
If I add spew.Dump callbacks everywhere it appears that a spew.Dump of the resulting value is called before a spew.Dump in the template callback function. This seems relevant...
A correction on the dump, it actually appears they are interleved with the resulting value starting first.
Thanks to Gareth I have also managed to get my unit tests to break by adding
to my test case.