Skip to content

Commit

Permalink
Merge branch 'edge' into app_fix-non-deterministic-odd-run-command
Browse files Browse the repository at this point in the history
  • Loading branch information
b-cooper committed May 1, 2024
2 parents 9870488 + f44872b commit 1a2dc21
Show file tree
Hide file tree
Showing 55 changed files with 1,194 additions and 143 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = {
'useLastRunCommandKey',
'useCurrentMaintenanceRun',
'useDeckConfigurationQuery',
'useAllCommandsAsPreSerializedList',
],
message:
'The HTTP hook is deprecated. Utilize the equivalent notification wrapper (useNotifyX) instead.',
Expand Down
22 changes: 22 additions & 0 deletions api-client/src/runs/commands/getCommandsAsPreSerializedList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GET, request } from '../../request'

import type { ResponsePromise } from '../../request'
import type { HostConfig } from '../../types'
import type {
CommandsAsPreSerializedListData,
GetCommandsParams,
} from './types'

export function getCommandsAsPreSerializedList(
config: HostConfig,
runId: string,
params: GetCommandsParams
): ResponsePromise<CommandsAsPreSerializedListData> {
return request<CommandsAsPreSerializedListData>(
GET,
`/runs/${runId}/commandsAsPreSerializedList`,
null,
config,
params
)
}
6 changes: 6 additions & 0 deletions api-client/src/runs/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export interface CommandsData {
links: CommandsLinks
}

export interface CommandsAsPreSerializedListData {
data: string[]
meta: GetCommandsParams & { totalLength: number }
links: CommandsLinks
}

export interface CreateCommandParams {
waitUntilComplete?: boolean
timeout?: number
Expand Down
1 change: 1 addition & 0 deletions api-client/src/runs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { createCommand } from './commands/createCommand'
export { createLiveCommand } from './commands/createLiveCommand'
export { getCommand } from './commands/getCommand'
export { getCommands } from './commands/getCommands'
export { getCommandsAsPreSerializedList } from './commands/getCommandsAsPreSerializedList'
export { createRunAction } from './createRunAction'
export * from './createLabwareOffset'
export * from './createLabwareDefinition'
Expand Down
20 changes: 20 additions & 0 deletions api-client/src/system/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, expect, it } from 'vitest'
import { sanitizeFileName } from '../utils'

describe('sanitizeFileName', () => {
it('returns original alphanumeric file name', () => {
expect(sanitizeFileName('an0ther_otie_logo.png')).toEqual(
'an0ther_otie_logo.png'
)
})

it('sanitizes a file name', () => {
expect(
sanitizeFileName(
`otie's birthday/party - (& the bouncy castle cost ~$100,000).jpeg`
)
).toEqual(
'otie_s_birthday_party_-____the_bouncy_castle_cost___100_000_.jpeg'
)
})
})
6 changes: 4 additions & 2 deletions api-client/src/system/createSplash.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { POST, request } from '../request'
import { sanitizeFileName } from './utils'
import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'

export function createSplash(
config: HostConfig,
file: File
): ResponsePromise<void> {
// sanitize file name to ensure no spaces
const renamedFile = new File([file], file.name.replace(' ', '_'), {
// sanitize file name to ensure no spaces or special characters
const newFileName = sanitizeFileName(file.name)
const renamedFile = new File([file], newFileName, {
type: 'image/png',
})

Expand Down
1 change: 1 addition & 0 deletions api-client/src/system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { createRegistration } from './createRegistration'
export { createSplash } from './createSplash'
export { getConnections } from './getConnections'
export * from './types'
export * from './utils'
3 changes: 3 additions & 0 deletions api-client/src/system/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function sanitizeFileName(fileName: string): string {
return fileName.replace(/[^a-zA-Z0-9-.]/gi, '_')
}
3 changes: 3 additions & 0 deletions api/src/opentrons/protocol_engine/state/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,9 @@ def handle_action(self, action: Action) -> None: # noqa: C901

elif isinstance(action, StopAction):
if not self._state.run_result:
if self._state.queue_status == QueueStatus.AWAITING_RECOVERY:
self._state.recovery_target_command_id = None

self._state.queue_status = QueueStatus.PAUSED
if action.from_estop:
self._state.stopped_by_estop = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,41 @@ def test_command_store_handles_stop_action(
assert subject.state.command_history.get_setup_queue_ids() == OrderedSet()


def test_command_store_handles_stop_action_when_awaiting_recovery() -> None:
"""It should mark the engine as non-gracefully stopped on StopAction."""
subject = CommandStore(is_door_open=False, config=_make_config())

subject.handle_action(
PlayAction(
requested_at=datetime(year=2021, month=1, day=1), deck_configuration=[]
)
)

subject.state.queue_status = QueueStatus.AWAITING_RECOVERY

subject.handle_action(StopAction())

assert subject.state == CommandState(
command_history=CommandHistory(),
queue_status=QueueStatus.PAUSED,
run_result=RunResult.STOPPED,
run_completed_at=None,
is_door_blocking=False,
run_error=None,
finish_error=None,
failed_command=None,
command_error_recovery_types={},
recovery_target_command_id=None,
run_started_at=datetime(year=2021, month=1, day=1),
latest_protocol_command_hash=None,
stopped_by_estop=False,
)
assert subject.state.command_history.get_running_command() is None
assert subject.state.command_history.get_all_ids() == []
assert subject.state.command_history.get_queue_ids() == OrderedSet()
assert subject.state.command_history.get_setup_queue_ids() == OrderedSet()


def test_command_store_cannot_restart_after_should_stop() -> None:
"""It should reject a play action after finish."""
subject = CommandStore(is_door_open=False, config=_make_config())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9496,7 +9496,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -9507,7 +9507,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -9629,7 +9629,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -9640,7 +9640,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 402.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -9762,7 +9762,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -9773,7 +9773,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -9895,7 +9895,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -9906,7 +9906,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 402.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10028,7 +10028,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10039,7 +10039,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10161,7 +10161,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10172,7 +10172,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 402.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10294,7 +10294,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10305,7 +10305,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10427,7 +10427,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10438,7 +10438,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 402.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10560,7 +10560,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10571,7 +10571,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10693,7 +10693,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10704,7 +10704,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 402.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10826,7 +10826,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10837,7 +10837,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 257.0,
"z": 40.0
}
Expand Down Expand Up @@ -10959,7 +10959,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashB3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -10970,7 +10970,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 402.25,
"y": 257.0,
"z": 40.0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@
"notes": [],
"params": {
"addressableAreaName": "movableTrashC3",
"alternateDropLocation": false,
"alternateDropLocation": true,
"forceDirect": false,
"ignoreTipConfiguration": true,
"offset": {
Expand All @@ -1272,7 +1272,7 @@
},
"result": {
"position": {
"x": 434.25,
"x": 466.25,
"y": 150.0,
"z": 40.0
}
Expand Down
Loading

0 comments on commit 1a2dc21

Please sign in to comment.