Skip to content

Commit 1358b2e

Browse files
authored
EH: Add basic qalter wrapper (#44)
* EH: Add basic qalter wrapper
1 parent 1e30fcd commit 1358b2e

File tree

4 files changed

+184
-0
lines changed

4 files changed

+184
-0
lines changed

pkg/qalter/v9.0/qalter.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*___INFO__MARK_BEGIN__*/
2+
/*************************************************************************
3+
* Copyright 2025 HPC-Gridware GmbH
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
************************************************************************/
18+
/*___INFO__MARK_END__*/
19+
20+
package qalter
21+
22+
// QAlter is the interface for the qalter command.
23+
type QAlter interface {
24+
NativeSpecification(args ...string) (string, error)
25+
}

pkg/qalter/v9.0/qalter_impl.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*___INFO__MARK_BEGIN__*/
2+
/*************************************************************************
3+
* Copyright 2025 HPC-Gridware GmbH
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
************************************************************************/
18+
/*___INFO__MARK_END__*/
19+
20+
package qalter
21+
22+
import (
23+
"bytes"
24+
"fmt"
25+
"os/exec"
26+
"time"
27+
)
28+
29+
type CommandLineQAlter struct {
30+
config CommandLineQAlterConfig
31+
}
32+
33+
type CommandLineQAlterConfig struct {
34+
Executable string
35+
DryRun bool
36+
// DelayAfter is the time to wait after executing a command.
37+
// This is useful for not overloading qmaster when 1000s of
38+
// configuration objects (like queues) are defined.
39+
DelayAfter time.Duration
40+
}
41+
42+
// NewCommandLineQAlter creates a new instance of CommandLineQAlter.
43+
func NewCommandLineQAlter(config CommandLineQAlterConfig) (*CommandLineQAlter, error) {
44+
if config.Executable == "" {
45+
config.Executable = "qalter"
46+
}
47+
return &CommandLineQAlter{config: config}, nil
48+
}
49+
50+
func (q *CommandLineQAlter) NativeSpecification(args []string) (string, error) {
51+
return q.RunCommand(args...)
52+
}
53+
54+
// RunCommand executes the qalter command with the specified arguments.
55+
func (c *CommandLineQAlter) RunCommand(args ...string) (string, error) {
56+
if c.config.DryRun {
57+
fmt.Printf("Executing: %s, %v", c.config.Executable, args)
58+
return "", nil
59+
}
60+
cmd := exec.Command(c.config.Executable, args...)
61+
var out bytes.Buffer
62+
cmd.Stdout = &out
63+
cmd.Stderr = &out
64+
// ensure that qalter returns a single line of output for each entry
65+
cmd.Env = append(cmd.Environ(), "SGE_SINGLE_LINE=true")
66+
err := cmd.Run()
67+
if c.config.DelayAfter != 0 {
68+
<-time.After(c.config.DelayAfter)
69+
}
70+
if err != nil {
71+
return out.String(), fmt.Errorf("failed to run command (%s): %v",
72+
out.String(), err)
73+
}
74+
return out.String(), err
75+
}

pkg/qalter/v9.0/qalter_impl_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*___INFO__MARK_BEGIN__*/
2+
/*************************************************************************
3+
* Copyright 2025 HPC-Gridware GmbH
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
************************************************************************/
18+
/*___INFO__MARK_END__*/
19+
20+
package qalter_test
21+
22+
import (
23+
. "github.com/onsi/ginkgo/v2"
24+
. "github.com/onsi/gomega"
25+
26+
qalter "github.com/hpc-gridware/go-clusterscheduler/pkg/qalter/v9.0"
27+
)
28+
29+
var _ = Describe("QalterImpl", func() {
30+
31+
Context("Basic functionality", func() {
32+
33+
It("should be able to create a new qalter instance", func() {
34+
qalter, err := qalter.NewCommandLineQAlter(qalter.CommandLineQAlterConfig{})
35+
Expect(qalter).NotTo(BeNil())
36+
Expect(err).To(BeNil())
37+
})
38+
39+
It("should be able to run in dry-run mode", func() {
40+
qalter, err := qalter.NewCommandLineQAlter(qalter.CommandLineQAlterConfig{
41+
DryRun: true,
42+
})
43+
Expect(qalter).NotTo(BeNil())
44+
Expect(err).To(BeNil())
45+
output, err := qalter.RunCommand("qalter", "-w", "p", "whymyjobnotrunning")
46+
Expect(err).To(BeNil())
47+
Expect(output).To(BeEmpty())
48+
})
49+
50+
})
51+
52+
})

pkg/qalter/v9.0/qalter_suite_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*___INFO__MARK_BEGIN__*/
2+
/*************************************************************************
3+
* Copyright 2025 HPC-Gridware GmbH
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
************************************************************************/
18+
/*___INFO__MARK_END__*/
19+
20+
package qalter_test
21+
22+
import (
23+
"testing"
24+
25+
. "github.com/onsi/ginkgo/v2"
26+
. "github.com/onsi/gomega"
27+
)
28+
29+
func TestV9_0(t *testing.T) {
30+
RegisterFailHandler(Fail)
31+
RunSpecs(t, "V9.0 QalterSuite")
32+
}

0 commit comments

Comments
 (0)