-
Notifications
You must be signed in to change notification settings - Fork 204
[Incremental] Add first file removal test #694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
davidungar
commented
Jun 2, 2021
- Adds a bunch of removal test options
- A facility for testing all combinations of them
- The first, most basic removal test,
- A fix for that test, that removes priors if incremental setup fails
fileprivate enum RemovalTestOption: String, CaseIterable, Comparable, Hashable, CustomStringConvertible { | ||
case | ||
removeInputFromInvocation, | ||
removeSourceFile, | ||
removeEntryFromOutputFileMap, | ||
removeSwiftDepsFile, | ||
restoreBadPriors | ||
|
||
private static let byInt = [Int: Self](uniqueKeysWithValues: allCases.enumerated().map{($0, $1)}) | ||
private static let intFor = [Self: Int](uniqueKeysWithValues: allCases.enumerated().map{($1, $0)}) | ||
|
||
var intValue: Int {Self.intFor[self]!} | ||
init(fromInt i: Int) {self = Self.byInt[i]!} | ||
|
||
static func < (lhs: RemovalTestOption, rhs: RemovalTestOption) -> Bool { | ||
lhs.intValue < rhs.intValue | ||
} | ||
var mask: Int { 1 << intValue} | ||
static let maxIntValue = allCases.map {$0.intValue} .max()! | ||
static let maxCombinedValue = (1 << maxIntValue) - 1 | ||
|
||
var description: String { rawValue } | ||
} | ||
|
||
/// Only 5 elements, an array is fine | ||
fileprivate typealias RemovalTestOptions = [RemovalTestOption] | ||
|
||
extension RemovalTestOptions { | ||
fileprivate static let allCombinations: [RemovalTestOptions] = | ||
(0...RemovalTestOption.maxCombinedValue) .map(decoding) | ||
|
||
fileprivate static func decoding(_ bits: Int) -> Self { | ||
RemovalTestOption.allCases.filter { opt in | ||
(1 << opt.intValue) & bits != 0 | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like a lot of work for something like an option set. However, it
- avoids manual, error-prone "= ... << 1" for every flag, and
- prints out symbolically, without code repeating the option names.
Is there a better way?
If not, should this stuff be factored into a protocol on the enumeration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know of a better way, and I think it's fine to leave as-is.
A protocol sounds like it'd be useful if we needed this more broadly but I don't think I can motivate that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Agreed!
@swift-ci please test |
@swift-ci please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of nits, but if you'd like to merge this and iterate on it to make sure these tests are running, please go ahead.
fileprivate enum RemovalTestOption: String, CaseIterable, Comparable, Hashable, CustomStringConvertible { | ||
case | ||
removeInputFromInvocation, | ||
removeSourceFile, | ||
removeEntryFromOutputFileMap, | ||
removeSwiftDepsFile, | ||
restoreBadPriors | ||
|
||
private static let byInt = [Int: Self](uniqueKeysWithValues: allCases.enumerated().map{($0, $1)}) | ||
private static let intFor = [Self: Int](uniqueKeysWithValues: allCases.enumerated().map{($1, $0)}) | ||
|
||
var intValue: Int {Self.intFor[self]!} | ||
init(fromInt i: Int) {self = Self.byInt[i]!} | ||
|
||
static func < (lhs: RemovalTestOption, rhs: RemovalTestOption) -> Bool { | ||
lhs.intValue < rhs.intValue | ||
} | ||
var mask: Int { 1 << intValue} | ||
static let maxIntValue = allCases.map {$0.intValue} .max()! | ||
static let maxCombinedValue = (1 << maxIntValue) - 1 | ||
|
||
var description: String { rawValue } | ||
} | ||
|
||
/// Only 5 elements, an array is fine | ||
fileprivate typealias RemovalTestOptions = [RemovalTestOption] | ||
|
||
extension RemovalTestOptions { | ||
fileprivate static let allCombinations: [RemovalTestOptions] = | ||
(0...RemovalTestOption.maxCombinedValue) .map(decoding) | ||
|
||
fileprivate static func decoding(_ bits: Int) -> Self { | ||
RemovalTestOption.allCases.filter { opt in | ||
(1 << opt.intValue) & bits != 0 | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know of a better way, and I think it's fine to leave as-is.
A protocol sounds like it'd be useful if we needed this more broadly but I don't think I can motivate that.
} | ||
|
||
func testRemoval(includeFailingCombos: Bool) throws { | ||
#if !os(Linux) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's special about Linux here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't recall at the moment, but these tests don't seem to work there. I'll file a radar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests don't work there. I'll file a radar on myself to investigate.
let knownGoodCombos: [[RemovalTestOption]] = [ | ||
[.removeInputFromInvocation], | ||
// next up: | ||
// [.removeInputFromInvocation, .restoreBadPriors], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: you probably mean some other case in this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, best to just remove the lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, removing the lines.
removeSwiftDeps(newInput) | ||
} | ||
if options.contains(.removeEntryFromOutputFileMap) { | ||
// FACTOR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which entry is removed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to removePreviouslyAddedInputFromOutputFileMap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed for clarity.
@swift-ci please test |
rdar://77998890 |