File: RandomTestWorkspaces.swift

package info (click to toggle)
swiftlang 6.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856,264 kB
  • sloc: cpp: 9,995,718; ansic: 2,234,019; asm: 1,092,167; python: 313,940; objc: 82,726; f90: 80,126; lisp: 38,373; pascal: 25,580; sh: 20,378; ml: 5,058; perl: 4,751; makefile: 4,725; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (117 lines) | stat: -rw-r--r-- 4,166 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SWBLibc
import Testing

// FIXME: Get a real random number generator.
private struct RandomNumberGenerator: Swift.RandomNumberGenerator {
    private var generator = SystemRandomNumberGenerator()

    /// Return a random number in the range 0 ... UInt64.max.
    mutating func next() -> UInt64 {
        return generator.next()
    }

    /// Return a random number in the range 0 ..< upperBound.
    mutating func uniform(lessThan upperBound: Int) -> Int {
        assert(upperBound < Int(UInt32.max), "FIXME: Unsupported")
        return Int(generator.next(upperBound: UInt32(upperBound)))
    }

    /// Return a random number over the range 0.0 ..< 1.0.
    mutating func probability() -> Double {
        var n = next()
        while true {
            n = next()
            if n != UInt64.max {
                return Double(next()) / Double(UInt64.max)
            }
        }
    }

    /// Select from among a set of weighted choices; the result is the index of the selection.
    mutating func select(from weights: [Int]) -> Int {
        // Pick a uniform N less than the sum.
        let sum = weights.reduce(0, +)
        var n = uniform(lessThan: sum)
        for (i,value) in weights.enumerated() {
            if n < value {
                return i
            }
            n -= value
        }
        fatalError("unreachable")
    }

    /// Split an input into N random pieces.
    mutating func split<T>(into n: Int, piecesOf input: [T]) -> [[T]] {
        // FIXME: This is not efficient.
        var results = (0 ..< n).map{ _ in [T]() }
        for item in input {
            results[uniform(lessThan: n)].append(item)
        }
        return results
    }
}

/// Generate a random test workspace.
package final class RandomWorkspaceBuilder {
    private var rng = RandomNumberGenerator()

    /// The total number of projects to generate.
    package var numProjects: Int = 1

    /// The total number of targets to generate, these will be random divided amongst the projects.
    package var numTargets: Int = 0

    /// The total number of files to generate, these will be randomly divided amongst the targets.
    package var numFiles: Int = 0

    package init() {
    }

    /// Generate a random workspace with the current parameters.
    package func generate() -> TestWorkspace {
        // Create all of the input files.
        let files = (0 ..< numFiles).map{ i -> TestFile in
            // FIXME: Pick a random file extension.
            let ext = "c"
            return TestFile("File-\(i).\(ext)")
        }

        // Create the targets, with files randomly divided.
        let targets = rng.split(into: numTargets, piecesOf: files).enumerated().map{ (entry) -> TestStandardTarget in
            let (i, files) = entry
            // FIXME: Pick type randomly.
            return TestStandardTarget("Target-\(i)", type: .staticLibrary, buildPhases: [
                    // FIXME: Pick phases randomly.
                    TestSourcesBuildPhase(files.map{ TestBuildFile($0.name) })
                ])
        }

        // FIXME: Create the random projects.
        assert(numProjects == 1, "FIXME: Unsupported")
        let project = TestProject("Project-0",
            groupTree: TestGroup("Sources", children: files),
            buildConfigurations: [
                TestBuildConfiguration("Debug", buildSettings: [
                        "PRODUCT_NAME": "$(TARGET_NAME)"]),
            ],
            targets: targets)

        return TestWorkspace("Random", sourceRoot: project.sourceRoot, projects: [project])
    }
}

@available(*, unavailable)
extension RandomWorkspaceBuilder: Sendable { }