diff --git a/pkg/common/types.go b/pkg/common/types.go index a3d4032..7760630 100644 --- a/pkg/common/types.go +++ b/pkg/common/types.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "sort" "strings" ) @@ -106,15 +107,14 @@ func (p *TopologyRequest) String() string { var sb strings.Builder sb.WriteString("TopologyRequest:\n") sb.WriteString(fmt.Sprintf(" Provider: %s\n", p.Provider.Name)) - sb.WriteString(" Credentials: ") - for key := range p.Provider.Creds { - sb.WriteString(fmt.Sprintf("%s=***,", key)) + sb.WriteString(map2string(p.Provider.Creds, " Credentials", true, "\n")) + sb.WriteString(fmt.Sprintf(" Engine: %s\n", p.Engine.Name)) + sb.WriteString(map2string(p.Engine.Params, " Parameters", false, "\n")) + sb.WriteString(" Nodes: ") + for _, nodes := range p.Nodes { + sb.WriteString(map2string(nodes.Instances, nodes.Region, false, " ")) } sb.WriteString("\n") - sb.WriteString(fmt.Sprintf(" Engine: %s\n", p.Engine.Name)) - sb.WriteString(fmt.Sprintf(" Parameters: %v\n", p.Engine.Params)) - sb.WriteString(fmt.Sprintf(" Nodes: %s\n", p.Nodes)) - return sb.String() } @@ -131,3 +131,29 @@ func GetTopologyRequest(body []byte) (*TopologyRequest, error) { return &payload, nil } + +func map2string(m map[string]string, prefix string, hide bool, suffix string) string { + var sb strings.Builder + sb.WriteString(prefix) + sb.WriteString(": [") + if n := len(m); n != 0 { + keys := make([]string, 0, n) + for key := range m { + keys = append(keys, key) + } + sort.Strings(keys) + terms := make([]string, 0, n) + for _, key := range keys { + if hide { + terms = append(terms, fmt.Sprintf("%s:***", key)) + } else { + terms = append(terms, fmt.Sprintf("%s:%s", key, m[key])) + } + } + sb.WriteString(strings.Join(terms, " ")) + } + sb.WriteString("]") + sb.WriteString(suffix) + + return sb.String() +} diff --git a/pkg/common/types_test.go b/pkg/common/types_test.go index 672bc64..ce9e863 100644 --- a/pkg/common/types_test.go +++ b/pkg/common/types_test.go @@ -35,10 +35,10 @@ func TestPayload(t *testing.T) { payload: &TopologyRequest{}, print: `TopologyRequest: Provider: - Credentials: + Credentials: [] Engine: - Parameters: map[] - Nodes: [] + Parameters: [] + Nodes: `, }, { @@ -123,10 +123,10 @@ func TestPayload(t *testing.T) { }, print: `TopologyRequest: Provider: aws - Credentials: access_key_id=***,secret_access_key=***, + Credentials: [access_key_id:*** secret_access_key:***] Engine: slurm - Parameters: map[block_sizes:30,120 plugin:topology/block] - Nodes: [{region1 map[instance1:node1 instance2:node2 instance3:node3]} {region2 map[instance4:node4 instance5:node5 instance6:node6]}] + Parameters: [block_sizes:30,120 plugin:topology/block] + Nodes: region1: [instance1:node1 instance2:node2 instance3:node3] region2: [instance4:node4 instance5:node5 instance6:node6] `, }, } diff --git a/pkg/translate/output.go b/pkg/translate/output.go index 8649aa6..28b85ef 100644 --- a/pkg/translate/output.go +++ b/pkg/translate/output.go @@ -34,7 +34,15 @@ func ToSLURM(wr io.Writer, root *common.Vertex) error { } func toBlockSLURM(wr io.Writer, root *common.Vertex, blocksizes string) error { - for _, block := range root.Vertices { + // sort the IDs + keys := make([]string, 0, len(root.Vertices)) + for key := range root.Vertices { + keys = append(keys, key) + } + sort.Strings(keys) + + for _, key := range keys { + block := root.Vertices[key] nodes := make([]string, 0, len(block.Vertices)) for _, node := range block.Vertices { nodes = append(nodes, node.Name) @@ -62,7 +70,16 @@ func toTreeSLURM(wr io.Writer, root *common.Vertex) error { parents = append(parents, v) } idToName[v.ID] = v.Name - for _, w := range v.Vertices { + + // sort the IDs + keys := make([]string, 0, len(v.Vertices)) + for key := range v.Vertices { + keys = append(keys, key) + } + sort.Strings(keys) + + for _, key := range keys { + w := v.Vertices[key] if len(w.Vertices) == 0 { // it's a leaf; don't add to queue _, ok := leaves[v.ID] if !ok { @@ -84,8 +101,16 @@ func toTreeSLURM(wr io.Writer, root *common.Vertex) error { } } } + + // sort leaves IDs + ids := make([]string, 0, len(leaves)) + for id := range leaves { + ids = append(ids, id) + } + sort.Strings(ids) var comment, switchName string - for sw, nodes := range leaves { + for _, sw := range ids { + nodes := leaves[sw] if idToName[sw] != "" { comment = fmt.Sprintf("# %s=%s\n", idToName[sw], sw) switchName = idToName[sw] diff --git a/pkg/translate/output_test.go b/pkg/translate/output_test.go index 1f4b36f..d17c259 100644 --- a/pkg/translate/output_test.go +++ b/pkg/translate/output_test.go @@ -25,24 +25,14 @@ import ( ) const ( - testTreeConfig1 = `SwitchName=S1 Switches=S[2-3] + testTreeConfig = `SwitchName=S1 Switches=S[2-3] SwitchName=S2 Nodes=Node[201-202],Node205 SwitchName=S3 Nodes=Node[304-306] ` - testTreeConfig2 = `SwitchName=S1 Switches=S[2-3] -SwitchName=S3 Nodes=Node[304-306] -SwitchName=S2 Nodes=Node[201-202],Node205 -` - - testBlockConfig1 = `BlockName=B1 Nodes=Node[104-106] + testBlockConfig = `BlockName=B1 Nodes=Node[104-106] BlockName=B2 Nodes=Node[201-202],Node205 BlockSizes=8 -` - - testBlockConfig2 = `BlockName=B2 Nodes=Node[201-202],Node205 -BlockName=B1 Nodes=Node[104-106] -BlockSizes=8 ` shortNameExpectedResult = `# switch.3.1=hpcislandid-1 @@ -63,12 +53,7 @@ func TestToTreeSLURM(t *testing.T) { buf := &bytes.Buffer{} err := ToSLURM(buf, v) require.NoError(t, err) - switch buf.String() { - case testTreeConfig1, testTreeConfig2: - // nop - default: - t.Errorf("unexpected result %s", buf.String()) - } + require.Equal(t, testTreeConfig, buf.String()) } func TestToBlockSLURM(t *testing.T) { @@ -76,12 +61,7 @@ func TestToBlockSLURM(t *testing.T) { buf := &bytes.Buffer{} err := ToSLURM(buf, v) require.NoError(t, err) - switch buf.String() { - case testBlockConfig1, testBlockConfig2: - // nop - default: - t.Errorf("unexpected result %s", buf.String()) - } + require.Equal(t, testBlockConfig, buf.String()) } func TestToSlurmNameShortener(t *testing.T) {