@Override
    public String toString() {
        if (isUnspecified())
            return "unspecified resources";

        StringBuilder sb = new StringBuilder("[vcpu: ");
        appendDouble(sb, vcpu);
        sb.append(", memory: ");
        appendDouble(sb, memoryGiB);
        sb.append(" Gb, disk: ");
        appendDouble(sb, diskGb);
        sb.append(" Gb");
        if (bandwidthGbps > 0) {
            sb.append(", bandwidth: ");
            appendDouble(sb, bandwidthGbps);
            sb.append(" Gbps");
        }
        if ( !diskSpeed.isDefault()) {
            sb.append(", disk speed: ").append(diskSpeed);
        }
        if ( !storageType.isDefault()) {
            sb.append(", storage type: ").append(storageType);
        }
        sb.append(", architecture: ").append(architecture);
        if ( !gpuResources.isDefault()) {
            sb.append(", gpu count: ").append(gpuResources.count());
            sb.append(", gpu memory: ");
            appendDouble(sb, gpuResources.memoryGiB());
            sb.append(" Gb");
        }
        sb.append(']');
        return sb.toString();
    }
@Test
    void testToString() {
        assertEquals("[vcpu: 1.0, memory: 10.0 Gb, disk: 100.0 Gb, architecture: any]",
                               new NodeResources(1., 10., 100., 0).toString());
        assertEquals("[vcpu: 0.3, memory: 3.3 Gb, disk: 33.3 Gb, bandwidth: 0.3 Gbps, architecture: any]",
                               new NodeResources(1 / 3., 10 / 3., 100 / 3., 0.3).toString());
        assertEquals("[vcpu: 0.7, memory: 9.0 Gb, disk: 66.7 Gb, bandwidth: 0.7 Gbps, architecture: any]",
                               new NodeResources(2 / 3., 8.97, 200 / 3., 0.67).toString());
    }