Skip to content

Commit 5e9f491

Browse files
committed
stembuild: vmconstruct extract ScriptExecutor
1 parent a91192a commit 5e9f491

File tree

4 files changed

+161
-92
lines changed

4 files changed

+161
-92
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package construct
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"time"
7+
8+
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/remotemanager"
9+
)
10+
11+
type ScriptExecutor struct {
12+
remoteManager remotemanager.RemoteManager
13+
}
14+
15+
func NewScriptExecutor(remoteManager remotemanager.RemoteManager) *ScriptExecutor {
16+
return &ScriptExecutor{
17+
remoteManager,
18+
}
19+
}
20+
21+
func (e *ScriptExecutor) ExecuteSetupScript(stembuildVersion string, setupFlags []string) error {
22+
var automationSetupScriptArgs []string
23+
automationSetupScriptArgs = append(automationSetupScriptArgs, fmt.Sprintf("-Version %s", stembuildVersion))
24+
25+
for _, arg := range setupFlags {
26+
automationSetupScriptArgs = append(automationSetupScriptArgs, fmt.Sprintf("-%s", arg))
27+
}
28+
29+
powershellCommand := fmt.Sprintf("powershell.exe %s %s", stemcellAutomationSetupScript, strings.Join(automationSetupScriptArgs, " "))
30+
_, err := e.remoteManager.ExecuteCommand(powershellCommand)
31+
return err
32+
}
33+
34+
func (e *ScriptExecutor) ExecutePostRebootScript(timeout time.Duration) error {
35+
_, err := e.remoteManager.ExecuteCommandWithTimeout("powershell.exe "+stemcellAutomationPostRebootScript, timeout)
36+
37+
if err != nil && strings.Contains(err.Error(), remotemanager.PowershellExecutionErrorMessage) {
38+
return err
39+
}
40+
41+
if err != nil {
42+
return fmt.Errorf("winrm connection event: %s", err)
43+
}
44+
45+
return nil
46+
47+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package construct_test
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"time"
7+
8+
. "github.com/onsi/ginkgo/v2"
9+
. "github.com/onsi/gomega"
10+
11+
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/construct"
12+
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/remotemanager"
13+
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/remotemanager/remotemanagerfakes"
14+
)
15+
16+
var _ = Describe("NewScriptExecutor", func() {
17+
var (
18+
fakeRemoteManager *remotemanagerfakes.FakeRemoteManager
19+
20+
scriptExecutor *construct.ScriptExecutor
21+
)
22+
23+
BeforeEach(func() {
24+
fakeRemoteManager = &remotemanagerfakes.FakeRemoteManager{}
25+
26+
scriptExecutor = construct.NewScriptExecutor(fakeRemoteManager)
27+
})
28+
29+
Describe("ScriptExecutor", func() {
30+
Describe("ExecuteSetupScript", func() {
31+
It("executes setup script with correct arguments", func() {
32+
version := "11.11.11"
33+
setupFlags := []string{"SomeFlag SomeValue", "OtherFlag OtherValue"}
34+
expectedCommandInvocation :=
35+
fmt.Sprintf(
36+
"powershell.exe %s -Version %s %s",
37+
`C:\provision\Setup.ps1`,
38+
version,
39+
"-SomeFlag SomeValue -OtherFlag OtherValue",
40+
)
41+
42+
err := scriptExecutor.ExecuteSetupScript(version, setupFlags)
43+
Expect(err).NotTo(HaveOccurred())
44+
45+
executeCommandCallArg := fakeRemoteManager.ExecuteCommandArgsForCall(0)
46+
47+
Expect(executeCommandCallArg).To(Equal(expectedCommandInvocation))
48+
})
49+
})
50+
51+
Describe("ExecutePostRebootScript", func() {
52+
var expectedTimeout time.Duration
53+
54+
BeforeEach(func() {
55+
expectedTimeout = 24 * time.Hour
56+
})
57+
58+
It("executes post-reboot script with correct arguments", func() {
59+
expectedCommandInvocation :=
60+
fmt.Sprintf(
61+
"powershell.exe %s",
62+
`C:\provision\PostReboot.ps1`,
63+
)
64+
65+
err := scriptExecutor.ExecutePostRebootScript(expectedTimeout)
66+
Expect(err).NotTo(HaveOccurred())
67+
68+
executeCommandWithTimeoutCallArg, actualTimeout := fakeRemoteManager.ExecuteCommandWithTimeoutArgsForCall(0)
69+
70+
Expect(executeCommandWithTimeoutCallArg).To(Equal(expectedCommandInvocation))
71+
Expect(expectedTimeout).To(Equal(actualTimeout))
72+
})
73+
74+
Context("when there is an error", func() {
75+
var commandExecutionErrorCode int
76+
var commandExecutionErr error
77+
78+
BeforeEach(func() {
79+
commandExecutionErrorCode = 999
80+
})
81+
82+
Context("when the error is a powershell execution error", func() {
83+
BeforeEach(func() {
84+
powershellErrorPrefix := errors.New(remotemanager.PowershellExecutionErrorMessage)
85+
commandExecutionErr = fmt.Errorf("%s: %s", powershellErrorPrefix, "a command failed to run")
86+
87+
fakeRemoteManager.ExecuteCommandWithTimeoutReturns(commandExecutionErrorCode, commandExecutionErr)
88+
})
89+
90+
It("returns the error", func() {
91+
err := scriptExecutor.ExecutePostRebootScript(expectedTimeout)
92+
93+
Expect(err).To(MatchError(commandExecutionErr))
94+
})
95+
})
96+
97+
Context("when the error is a NOT powershell execution error", func() {
98+
BeforeEach(func() {
99+
commandExecutionErr = errors.New("fake-non-powershell-execution-error")
100+
})
101+
102+
It("wraps a non-powershell execution error", func() {
103+
fakeRemoteManager.ExecuteCommandWithTimeoutReturns(1, commandExecutionErr)
104+
105+
err := scriptExecutor.ExecutePostRebootScript(expectedTimeout)
106+
107+
Expect(err).To(HaveOccurred())
108+
Expect(err.Error()).To(Equal(fmt.Sprintf("winrm connection event: %s", commandExecutionErr.Error())))
109+
})
110+
})
111+
})
112+
})
113+
})
114+
})

stembuild/construct/vmconstruct.go

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -252,44 +252,6 @@ func (c *VMConstruct) logOutUsers() error {
252252
return nil
253253
}
254254

255-
type ScriptExecutor struct {
256-
remoteManager remotemanager.RemoteManager
257-
}
258-
259-
func NewScriptExecutor(remoteManager remotemanager.RemoteManager) *ScriptExecutor {
260-
return &ScriptExecutor{
261-
remoteManager,
262-
}
263-
}
264-
265-
func (e *ScriptExecutor) ExecuteSetupScript(stembuildVersion string, setupFlags []string) error {
266-
var automationSetupScriptArgs []string
267-
automationSetupScriptArgs = append(automationSetupScriptArgs, fmt.Sprintf("-Version %s", stembuildVersion))
268-
269-
for _, arg := range setupFlags {
270-
automationSetupScriptArgs = append(automationSetupScriptArgs, fmt.Sprintf("-%s", arg))
271-
}
272-
273-
powershellCommand := fmt.Sprintf("powershell.exe %s %s", stemcellAutomationSetupScript, strings.Join(automationSetupScriptArgs, " "))
274-
_, err := e.remoteManager.ExecuteCommand(powershellCommand)
275-
return err
276-
}
277-
278-
func (e *ScriptExecutor) ExecutePostRebootScript(timeout time.Duration) error {
279-
_, err := e.remoteManager.ExecuteCommandWithTimeout("powershell.exe "+stemcellAutomationPostRebootScript, timeout)
280-
281-
if err != nil && strings.Contains(err.Error(), remotemanager.PowershellExecutionErrorMessage) {
282-
return err
283-
}
284-
285-
if err != nil {
286-
return fmt.Errorf("winrm connection event: %s", err)
287-
}
288-
289-
return nil
290-
291-
}
292-
293255
func (c *VMConstruct) isPoweredOff(duration time.Duration) error {
294256
const timeStampFormat = "2006-01-02T15:04:05.999999-07:00"
295257
err := c.poller.Poll(duration, func() (bool, error) {

stembuild/construct/vmconstruct_test.go

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/construct/constructfakes"
1616
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/messenger"
1717
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/poller/pollerfakes"
18-
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/remotemanager"
1918
"github.com/cloudfoundry/bosh-windows-stemcell-builder/stembuild/remotemanager/remotemanagerfakes"
2019
)
2120

@@ -108,59 +107,6 @@ var _ = Describe("construct_helpers", func() {
108107
vmConstruct.RebootWaitTime = 0
109108
})
110109

111-
Describe("ScriptExecutor", func() {
112-
It("executes setup script with correct arguments", func() {
113-
e := construct.NewScriptExecutor(fakeRemoteManager)
114-
version := "11.11.11"
115-
err := e.ExecuteSetupScript(version, fakeSetupFlags)
116-
executeCommandCallArg := fakeRemoteManager.ExecuteCommandArgsForCall(0)
117-
118-
Expect(err).NotTo(HaveOccurred())
119-
Expect(executeCommandCallArg).To(ContainSubstring("powershell"))
120-
Expect(executeCommandCallArg).To(ContainSubstring("Setup.ps1"))
121-
Expect(executeCommandCallArg).To(ContainSubstring(" -Version " + version))
122-
Expect(executeCommandCallArg).To(ContainSubstring(" -SomeFlag SomeValue"))
123-
Expect(executeCommandCallArg).To(ContainSubstring(" -OtherFlag OtherValue"))
124-
})
125-
126-
It("executes post-reboot script with correct arguments", func() {
127-
e := construct.NewScriptExecutor(fakeRemoteManager)
128-
superLongTimeout := 24 * time.Hour
129-
err := e.ExecutePostRebootScript(superLongTimeout)
130-
executeCommandCallArg, timeout := fakeRemoteManager.ExecuteCommandWithTimeoutArgsForCall(0)
131-
132-
Expect(err).NotTo(HaveOccurred())
133-
Expect(executeCommandCallArg).To(ContainSubstring("powershell"))
134-
Expect(executeCommandCallArg).To(ContainSubstring("PostReboot.ps1"))
135-
Expect(timeout).To(Equal(superLongTimeout))
136-
})
137-
138-
It("returns an error when there is a powershell script execution error", func() {
139-
e := construct.NewScriptExecutor(fakeRemoteManager)
140-
superLongTimeout := 24 * time.Hour
141-
powershellErrorPrefix := errors.New(remotemanager.PowershellExecutionErrorMessage)
142-
powershellErr := fmt.Errorf("%s: %s", powershellErrorPrefix, "a command failed to run")
143-
fakeRemoteManager.ExecuteCommandWithTimeoutReturns(2, powershellErr)
144-
145-
err := e.ExecutePostRebootScript(superLongTimeout)
146-
147-
Expect(err).To(MatchError(powershellErr))
148-
})
149-
150-
It("wraps a non-powershell execution error", func() {
151-
e := construct.NewScriptExecutor(fakeRemoteManager)
152-
superLongTimeout := 24 * time.Hour
153-
winRMError := errors.New("some EOF thing")
154-
155-
fakeRemoteManager.ExecuteCommandWithTimeoutReturns(1, winRMError)
156-
157-
err := e.ExecutePostRebootScript(superLongTimeout)
158-
159-
Expect(err).To(HaveOccurred())
160-
Expect(err.Error()).To(ContainSubstring("winrm connection event"))
161-
})
162-
})
163-
164110
Describe("PrepareVM", func() {
165111
Describe("creates provision directory", func() {
166112
Context("when it fails", func() {

0 commit comments

Comments
 (0)