From d5a159baabab2cb64bc1c3d6342cafade889ee49 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Fri, 10 Jul 2026 21:14:01 +0200 Subject: [PATCH 01/14] monitor: extract GroupStateContext + pure health predicates Introduce GroupStateContext, a struct that bundles every input the node_active protocol FSM needs: - activeNode, groupNodeList (loaded once from the DB) - formation (loaded once instead of twice) - now (single TimestampTz snapshot instead of per-call GetCurrentTimestamp()) - GUC copies: unhealthyTimeoutMs, drainTimeoutMs, startupGracePeriodMs BuildGroupStateContext() does a single DB read phase, replacing the redundant AutoFailoverNodeGroup() call in ProceedGroupStateForMSFailover and the second GetFormation() call in ProceedGroupStateForPrimaryNode. ProceedGroupState() is now a thin wrapper that builds the context and delegates to ProceedGroupStateFromContext(). The latter is exported so test code can populate a context from fixtures and exercise the FSM without a live DB connection. Add NodeIsHealthy/NodeIsUnhealthy/NodeIsReporting/NodeIsDrainTimeExpired alongside the existing IsHealthy/IsUnhealthy/IsReporting/IsDrainTimeExpired shims. The new variants take a const GroupStateContext * instead of calling GetCurrentTimestamp() or reading GUC globals, making the FSM decisions deterministic for a given context snapshot. All call sites inside group_state_machine.c now use the pure variants. --- src/monitor/group_state_machine.c | 160 +++++++++++++++++++----------- src/monitor/group_state_machine.h | 30 ++++++ src/monitor/node_metadata.c | 94 ++++++++++++++++++ src/monitor/node_metadata.h | 16 +++ 4 files changed, 243 insertions(+), 57 deletions(-) diff --git a/src/monitor/group_state_machine.c b/src/monitor/group_state_machine.c index cf2b3e4e4..145ad6ba6 100644 --- a/src/monitor/group_state_machine.c +++ b/src/monitor/group_state_machine.c @@ -52,16 +52,19 @@ typedef struct CandidateList /* private function forward declarations */ -static bool ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode); -static bool ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, +static bool ProceedGroupStateForPrimaryNode(GroupStateContext *ctx, + AutoFailoverNode *primaryNode); +static bool ProceedGroupStateForMSFailover(GroupStateContext *ctx, AutoFailoverNode *primaryNode); static bool ProceedWithMSFailover(AutoFailoverNode *activeNode, AutoFailoverNode *candidateNode); -static bool BuildCandidateList(List *standbyNodesGroupList, +static bool BuildCandidateList(GroupStateContext *ctx, + List *standbyNodesGroupList, CandidateList *candidateList); -static AutoFailoverNode * SelectFailoverCandidateNode(CandidateList *candidateList, +static AutoFailoverNode * SelectFailoverCandidateNode(GroupStateContext *ctx, + CandidateList *candidateList, AutoFailoverNode *primaryNode); static bool PromoteSelectedNode(AutoFailoverNode *selectedNode, @@ -80,27 +83,72 @@ int PromoteXlogThreshold = DEFAULT_XLOG_SEG_SIZE; /* - * ProceedGroupState proceeds the state machines of the group of which - * the given node is part. + * BuildGroupStateContext loads everything from the database that the + * node_active FSM needs, capturing a single timestamp snapshot and copying + * the current GUC values. Call this once at the top of NodeActive() and pass + * the resulting context to ProceedGroupStateFromContext(). + * + * Returns false (and raises an ereport ERROR) when the formation cannot be + * found. */ bool -ProceedGroupState(AutoFailoverNode *activeNode) +BuildGroupStateContext(GroupStateContext *ctx, AutoFailoverNode *activeNode) { - char *formationId = activeNode->formationId; - int groupId = activeNode->groupId; - - AutoFailoverFormation *formation = GetFormation(formationId); - - List *nodesGroupList = AutoFailoverNodeGroup(formationId, groupId); - int nodesCount = list_length(nodesGroupList); + ctx->formationId = activeNode->formationId; + ctx->groupId = activeNode->groupId; + ctx->activeNode = activeNode; + ctx->formation = GetFormation(activeNode->formationId); + ctx->groupNodeList = + AutoFailoverNodeGroup(activeNode->formationId, activeNode->groupId); + ctx->groupNodeCount = list_length(ctx->groupNodeList); + ctx->now = GetCurrentTimestamp(); + ctx->unhealthyTimeoutMs = UnhealthyTimeoutMs; + ctx->drainTimeoutMs = DrainTimeoutMs; + ctx->startupGracePeriodMs = StartupGracePeriodMs; - if (formation == NULL) + if (ctx->formation == NULL) { ereport(ERROR, (errmsg("Formation for %s could not be found", activeNode->formationId))); } + return true; +} + + +/* + * ProceedGroupState proceeds the state machines of the group of which + * the given node is part. It builds a GroupStateContext from the database and + * delegates to ProceedGroupStateFromContext. + */ +bool +ProceedGroupState(AutoFailoverNode *activeNode) +{ + GroupStateContext ctx; + + BuildGroupStateContext(&ctx, activeNode); + + return ProceedGroupStateFromContext(&ctx); +} + + +/* + * ProceedGroupStateFromContext is the core FSM logic, operating entirely on + * the pre-built GroupStateContext. It does not touch the database for reads; + * writes (AssignGoalState, NotifyStateChange) still go to the DB. + * + * This separation lets test code inject a synthetic context and exercise the + * FSM without a live database connection. + */ +bool +ProceedGroupStateFromContext(GroupStateContext *ctx) +{ + AutoFailoverNode *activeNode = ctx->activeNode; + char *formationId = ctx->formationId; + int groupId = ctx->groupId; + int nodesCount = ctx->groupNodeCount; + /* * If the active node just reached the DROPPED state, proceed to remove it * from the pgautofailover.node table. @@ -191,7 +239,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsInPrimaryState(activeNode)) { - return ProceedGroupStateForPrimaryNode(activeNode); + return ProceedGroupStateForPrimaryNode(ctx, activeNode); } AutoFailoverNode *primaryNode = @@ -214,7 +262,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) * * In all other cases we require a primaryNode to be identified. */ - if (primaryNode == NULL && !IsFailoverInProgress(nodesGroupList)) + if (primaryNode == NULL && !IsFailoverInProgress(ctx->groupNodeList)) { ereport(ERROR, (errmsg("ProceedGroupState couldn't find the primary node " @@ -227,7 +275,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) } /* Multiple Standby failover is handled in its own function. */ - if (nodesCount > 2 && IsUnhealthy(primaryNode)) + if (nodesCount > 2 && NodeIsUnhealthy(primaryNode, ctx)) { /* * The WAIT_PRIMARY state encodes the fact that we know there is no @@ -293,7 +341,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) * stop here. When it return false, it did nothing, and so we want to * apply the common orchestration code for a failover. */ - if (ProceedGroupStateForMSFailover(activeNode, primaryNode)) + if (ProceedGroupStateForMSFailover(ctx, primaryNode)) { return true; } @@ -310,7 +358,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) if (IsCurrentState(activeNode, REPLICATION_STATE_REPORT_LSN) && (IsCurrentState(primaryNode, REPLICATION_STATE_WAIT_PRIMARY) || IsCurrentState(primaryNode, REPLICATION_STATE_JOIN_PRIMARY)) && - IsHealthy(primaryNode)) + NodeIsHealthy(primaryNode, ctx)) { char message[BUFSIZE] = { 0 }; @@ -335,7 +383,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_REPORT_LSN) && IsCurrentState(primaryNode, REPLICATION_STATE_PRIMARY) && - IsHealthy(primaryNode)) + NodeIsHealthy(primaryNode, ctx)) { char message[BUFSIZE]; @@ -378,7 +426,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) if (IsCurrentState(activeNode, REPLICATION_STATE_REPORT_LSN) || IsCurrentState(activeNode, REPLICATION_STATE_FAST_FORWARD)) { - return ProceedGroupStateForMSFailover(activeNode, primaryNode); + return ProceedGroupStateForMSFailover(ctx, primaryNode); } /* @@ -473,7 +521,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) (IsCurrentState(primaryNode, REPLICATION_STATE_WAIT_PRIMARY) || IsCurrentState(primaryNode, REPLICATION_STATE_JOIN_PRIMARY) || IsCurrentState(primaryNode, REPLICATION_STATE_PRIMARY)) && - IsHealthy(activeNode) && + NodeIsHealthy(activeNode, ctx) && activeNode->reportedTLI == primaryNode->reportedTLI && WalDifferenceWithin(activeNode, primaryNode, EnableSyncXlogThreshold)) { @@ -498,7 +546,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_SECONDARY) && IsInPrimaryState(primaryNode) && - IsUnhealthy(primaryNode) && IsHealthy(activeNode) && + NodeIsUnhealthy(primaryNode, ctx) && NodeIsHealthy(activeNode, ctx) && activeNode->candidatePriority > 0 && WalDifferenceWithin(activeNode, primaryNode, PromoteXlogThreshold)) { @@ -603,7 +651,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_PREPARE_PROMOTION) && primaryNode && - IsCitusFormation(formation) && activeNode->groupId > 0) + IsCitusFormation(ctx->formation) && activeNode->groupId > 0) { char message[BUFSIZE]; @@ -630,7 +678,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_PREPARE_PROMOTION) && primaryNode == NULL && - IsCitusFormation(formation) && activeNode->groupId > 0) + IsCitusFormation(ctx->formation) && activeNode->groupId > 0) { char message[BUFSIZE]; @@ -735,7 +783,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_STOP_REPLICATION) && (IsCurrentState(primaryNode, REPLICATION_STATE_DEMOTE_TIMEOUT) || - IsDrainTimeExpired(primaryNode))) + NodeIsDrainTimeExpired(primaryNode, ctx))) { char message[BUFSIZE]; @@ -762,7 +810,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_STOP_REPLICATION) && primaryNode && - IsCitusFormation(formation) && activeNode->groupId > 0) + IsCitusFormation(ctx->formation) && activeNode->groupId > 0) { char message[BUFSIZE]; @@ -789,7 +837,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) */ if (IsCurrentState(activeNode, REPLICATION_STATE_STOP_REPLICATION) && primaryNode == NULL && - IsCitusFormation(formation) && activeNode->groupId > 0) + IsCitusFormation(ctx->formation) && activeNode->groupId > 0) { char message[BUFSIZE]; @@ -815,7 +863,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) * concurrently making progress. */ if (IsCurrentState(activeNode, REPLICATION_STATE_DEMOTED) && - IsHealthy(primaryNode) && + NodeIsHealthy(primaryNode, ctx) && ((primaryNode->reportedState == REPLICATION_STATE_WAIT_PRIMARY || primaryNode->reportedState == REPLICATION_STATE_JOIN_PRIMARY) && primaryNode->goalState == REPLICATION_STATE_PRIMARY)) @@ -841,7 +889,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) * demoted -> catchingup */ if (IsCurrentState(activeNode, REPLICATION_STATE_DEMOTED) && - IsHealthy(primaryNode) && + NodeIsHealthy(primaryNode, ctx) && (IsCurrentState(primaryNode, REPLICATION_STATE_JOIN_PRIMARY) || IsCurrentState(primaryNode, REPLICATION_STATE_WAIT_PRIMARY) || IsCurrentState(primaryNode, REPLICATION_STATE_PRIMARY))) @@ -898,7 +946,7 @@ ProceedGroupState(AutoFailoverNode *activeNode) AssignGoalState(activeNode, REPLICATION_STATE_SECONDARY, message); /* compute next step for the primary depending on node settings */ - return ProceedGroupStateForPrimaryNode(primaryNode); + return ProceedGroupStateForPrimaryNode(ctx, primaryNode); } /* @@ -935,7 +983,8 @@ ProceedGroupState(AutoFailoverNode *activeNode) * Group State Machine when a primary node contacts the monitor. */ static bool -ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) +ProceedGroupStateForPrimaryNode(GroupStateContext *ctx, + AutoFailoverNode *primaryNode) { List *otherNodesGroupList = AutoFailoverOtherNodesList(primaryNode); int otherNodesCount = list_length(otherNodesGroupList); @@ -1011,8 +1060,6 @@ ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) int secondaryNodesCount = otherNodesCount; int secondaryQuorumNodesCount = otherNodesCount; - AutoFailoverFormation *formation = - GetFormation(primaryNode->formationId); ListCell *nodeCell = NULL; foreach(nodeCell, otherNodesGroupList) @@ -1029,7 +1076,7 @@ ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) if (otherNode->goalState == REPLICATION_STATE_SECONDARY && otherNode->reportedState != REPLICATION_STATE_REPORT_LSN && otherNode->reportedState != REPLICATION_STATE_JOIN_SECONDARY && - IsUnhealthy(otherNode)) + NodeIsUnhealthy(otherNode, ctx)) { char message[BUFSIZE]; @@ -1078,7 +1125,7 @@ ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) */ if (replicationQuorumCount == 0) { - Assert(formation->number_sync_standbys == 0); + Assert(ctx->formation->number_sync_standbys == 0); ReplicationState primaryGoalState = secondaryNodesCount == 0 @@ -1133,7 +1180,7 @@ ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) * block writes on the primary. */ ReplicationState primaryGoalState = - formation->number_sync_standbys == 0 + ctx->formation->number_sync_standbys == 0 ? REPLICATION_STATE_WAIT_PRIMARY : REPLICATION_STATE_PRIMARY; @@ -1199,7 +1246,7 @@ ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) char message[BUFSIZE] = { 0 }; ReplicationState primaryGoalState = - formation->number_sync_standbys == 0 && + ctx->formation->number_sync_standbys == 0 && secondaryQuorumNodesCount == 0 ? REPLICATION_STATE_WAIT_PRIMARY : REPLICATION_STATE_PRIMARY; @@ -1255,11 +1302,11 @@ ProceedGroupStateForPrimaryNode(AutoFailoverNode *primaryNode) * - there's more than one standby node registered in the system */ static bool -ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, +ProceedGroupStateForMSFailover(GroupStateContext *ctx, AutoFailoverNode *primaryNode) { - List *nodesGroupList = - AutoFailoverNodeGroup(activeNode->formationId, activeNode->groupId); + AutoFailoverNode *activeNode = ctx->activeNode; + List *nodesGroupList = ctx->groupNodeList; /* already fetched in context */ CandidateList candidateList = { 0 }; /* @@ -1310,7 +1357,7 @@ ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, * started yet. */ if (IsStateIn(nodeBeingPromoted->reportedState, knownUnreachableStates) || - IsHealthy(nodeBeingPromoted)) + NodeIsHealthy(nodeBeingPromoted, ctx)) { elog(LOG, "Found candidate " NODE_FORMAT, NODE_FORMAT_ARGS(nodeBeingPromoted)); @@ -1338,12 +1385,9 @@ ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, * different candidateNodesGroupList in which every node has reported their * LSN position, allowing progress to be made. */ - char *formationId = activeNode->formationId; - AutoFailoverFormation *formation = GetFormation(formationId); - - candidateList.numberSyncStandbys = formation->number_sync_standbys; + candidateList.numberSyncStandbys = ctx->formation->number_sync_standbys; - BuildCandidateList(nodesGroupList, &candidateList); + BuildCandidateList(ctx, nodesGroupList, &candidateList); /* * Time to select a candidate? @@ -1385,7 +1429,7 @@ ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, * WAIT_PRIMARY state with all the writes blocked for lack of standby * nodes. */ - int minCandidates = formation->number_sync_standbys + 1; + int minCandidates = ctx->formation->number_sync_standbys + 1; /* no candidates is a hard pass */ if (candidateList.candidateCount == 0) @@ -1407,8 +1451,8 @@ ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, " and reported state \"%s\"", candidateList.quorumCandidateCount, minCandidates, - formation->number_sync_standbys, - formation->formationId, + ctx->formation->number_sync_standbys, + ctx->formation->formationId, NODE_FORMAT_ARGS(activeNode), ReplicationStateGetName(activeNode->reportedState)); @@ -1457,7 +1501,7 @@ ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, } AutoFailoverNode *selectedNode = - SelectFailoverCandidateNode(&candidateList, primaryNode); + SelectFailoverCandidateNode(ctx, &candidateList, primaryNode); /* we might not have a selected candidate for failover yet */ if (selectedNode == NULL) @@ -1507,7 +1551,8 @@ ProceedGroupStateForMSFailover(AutoFailoverNode *activeNode, * caller for BuildCandidateList knows to refrain from any decision making. */ static bool -BuildCandidateList(List *nodesGroupList, CandidateList *candidateList) +BuildCandidateList(GroupStateContext *ctx, List *nodesGroupList, + CandidateList *candidateList) { ListCell *nodeCell = NULL; List *candidateNodesGroupList = NIL; @@ -1550,7 +1595,7 @@ BuildCandidateList(List *nodesGroupList, CandidateList *candidateList) * unless the node is unhealthy because Postgres is down, but * pg_autoctl is still reporting. */ - if (IsUnhealthy(node) && !IsReporting(node)) + if (NodeIsUnhealthy(node, ctx) && !NodeIsReporting(node, ctx)) { elog(LOG, "Skipping candidate " NODE_FORMAT ", which is unhealthy", @@ -1717,7 +1762,8 @@ ProceedWithMSFailover(AutoFailoverNode *activeNode, * the next step (cascade WALs or promote directly). */ static AutoFailoverNode * -SelectFailoverCandidateNode(CandidateList *candidateList, +SelectFailoverCandidateNode(GroupStateContext *ctx, + CandidateList *candidateList, AutoFailoverNode *primaryNode) { /* @@ -1789,7 +1835,7 @@ SelectFailoverCandidateNode(CandidateList *candidateList, AutoFailoverNode *node = (AutoFailoverNode *) lfirst(nodeCell); /* all the candidates are now in the REPORT_LSN state */ - if (IsUnhealthy(node)) + if (NodeIsUnhealthy(node, ctx)) { char message[BUFSIZE]; @@ -1840,7 +1886,7 @@ SelectFailoverCandidateNode(CandidateList *candidateList, { AutoFailoverNode *node = (AutoFailoverNode *) lfirst(nodeCell); - if (IsHealthy(node)) + if (NodeIsHealthy(node, ctx)) { someMostAdvancedStandbysAreHealthy = true; break; diff --git a/src/monitor/group_state_machine.h b/src/monitor/group_state_machine.h index bab91395c..65e9f0fac 100644 --- a/src/monitor/group_state_machine.h +++ b/src/monitor/group_state_machine.h @@ -15,6 +15,8 @@ #include "postgres.h" #include "access/xlogdefs.h" +#include "datatype/timestamp.h" +#include "formation_metadata.h" #include "node_metadata.h" /* @@ -34,8 +36,36 @@ typedef struct AutoFailoverNodeState } AutoFailoverNodeState; +/* + * GroupStateContext bundles every input the monitor node_active protocol needs + * to make FSM decisions: the node list (loaded once from the DB), the + * formation, a single timestamp snapshot, and copies of the relevant GUCs. + * + * Production code builds this with BuildGroupStateContext(), which fetches + * everything from the database. Test code can populate it from fixtures and + * call ProceedGroupStateFromContext() directly, making the FSM logic + * exercisable without a live database. + */ +typedef struct GroupStateContext +{ + char *formationId; + int groupId; + AutoFailoverNode *activeNode; + List *groupNodeList; + int groupNodeCount; + AutoFailoverFormation *formation; + TimestampTz now; + int unhealthyTimeoutMs; + int drainTimeoutMs; + int startupGracePeriodMs; +} GroupStateContext; + + /* public function declarations */ +extern bool BuildGroupStateContext(GroupStateContext *ctx, + AutoFailoverNode *activeNode); extern bool ProceedGroupState(AutoFailoverNode *activeNode); +extern bool ProceedGroupStateFromContext(GroupStateContext *ctx); /* GUCs */ extern int EnableSyncXlogThreshold; diff --git a/src/monitor/node_metadata.c b/src/monitor/node_metadata.c index 34fb6adc6..fb6bcf18b 100644 --- a/src/monitor/node_metadata.c +++ b/src/monitor/node_metadata.c @@ -2036,3 +2036,97 @@ IsDrainTimeExpired(AutoFailoverNode *pgAutoFailoverNode) return drainTimeExpired; } + + +/* + * NodeIsHealthy is the context-pure variant of IsHealthy. It uses the + * timestamp snapshot in ctx->now instead of calling GetCurrentTimestamp(). + */ +bool +NodeIsHealthy(const AutoFailoverNode *node, const struct GroupStateContext *ctx) +{ + int nodeActiveCallsFrequencyMs = 1 * 1000; + + if (node == NULL) + { + return false; + } + + if (node->health == NODE_HEALTH_BAD && + TimestampDifferenceExceeds(node->healthCheckTime, node->reportTime, 0) && + !TimestampDifferenceExceeds(node->reportTime, ctx->now, + nodeActiveCallsFrequencyMs)) + { + return node->pgIsRunning; + } + + return node->health == NODE_HEALTH_GOOD && node->pgIsRunning; +} + + +/* + * NodeIsUnhealthy is the context-pure variant of IsUnhealthy. + */ +bool +NodeIsUnhealthy(const AutoFailoverNode *node, const struct GroupStateContext *ctx) +{ + if (node == NULL) + { + return true; + } + + if (TimestampDifferenceExceeds(node->reportTime, ctx->now, + ctx->unhealthyTimeoutMs)) + { + if (node->health == NODE_HEALTH_BAD && + TimestampDifferenceExceeds(PgStartTime, node->healthCheckTime, 0)) + { + if (TimestampDifferenceExceeds(PgStartTime, ctx->now, + ctx->startupGracePeriodMs)) + { + return true; + } + } + } + + if (!node->pgIsRunning) + { + return true; + } + + return false; +} + + +/* + * NodeIsReporting is the context-pure variant of IsReporting. + */ +bool +NodeIsReporting(const AutoFailoverNode *node, const struct GroupStateContext *ctx) +{ + if (node == NULL) + { + return false; + } + + return !TimestampDifferenceExceeds(node->reportTime, ctx->now, + ctx->unhealthyTimeoutMs); +} + + +/* + * NodeIsDrainTimeExpired is the context-pure variant of IsDrainTimeExpired. + */ +bool +NodeIsDrainTimeExpired(const AutoFailoverNode *node, + const struct GroupStateContext *ctx) +{ + if (node == NULL || + node->goalState != REPLICATION_STATE_DEMOTE_TIMEOUT) + { + return false; + } + + return TimestampDifferenceExceeds(node->stateChangeTime, ctx->now, + ctx->drainTimeoutMs); +} diff --git a/src/monitor/node_metadata.h b/src/monitor/node_metadata.h index 607cf8bd9..6c7440b6e 100644 --- a/src/monitor/node_metadata.h +++ b/src/monitor/node_metadata.h @@ -241,3 +241,19 @@ extern bool IsHealthy(AutoFailoverNode *pgAutoFailoverNode); extern bool IsUnhealthy(AutoFailoverNode *pgAutoFailoverNode); extern bool IsDrainTimeExpired(AutoFailoverNode *pgAutoFailoverNode); extern bool IsReporting(AutoFailoverNode *pgAutoFailoverNode); + +/* + * Pure (context-based) variants of the health predicates. They take a + * pre-captured GroupStateContext instead of calling GetCurrentTimestamp() or + * reading GUC globals themselves. Forward-declare the struct here to avoid a + * circular dependency between node_metadata.h and group_state_machine.h. + */ +struct GroupStateContext; +extern bool NodeIsHealthy(const AutoFailoverNode *node, + const struct GroupStateContext *ctx); +extern bool NodeIsUnhealthy(const AutoFailoverNode *node, + const struct GroupStateContext *ctx); +extern bool NodeIsReporting(const AutoFailoverNode *node, + const struct GroupStateContext *ctx); +extern bool NodeIsDrainTimeExpired(const AutoFailoverNode *node, + const struct GroupStateContext *ctx); From 0fd047ba88573ea06e2eb6e1ea6f115537e00305 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Fri, 10 Jul 2026 21:18:35 +0200 Subject: [PATCH 02/14] pgaftest: add node_active protocol test commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two new DSL commands for testing the monitor's node_active protocol: node_active { node2 reported: secondary lsn: 0/5A0 tli: 1 pgrunning: true } expect { assigned: secondary } mark healthy: node2 mark unhealthy: node3 node_active calls pgautofailover.node_active() on the monitor container via psql, then asserts the returned assigned_group_state matches the expected value in the expect block. The block content is read as a raw string and key-value pairs are parsed in C, keeping the grammar simple. mark healthy/unhealthy directly updates the health column in pgautofailover.node, mirroring what the health-check worker does, so tests can place a node in a known health state before calling node_active. Changes: test_spec.h — CMD_NODE_ACTIVE, CMD_MARK_HEALTH, new TestCmd fields test_spec_scan.l — keywords: node_active, mark, healthy, unhealthy, ':' test_spec_parse.y — node_active_cmd and mark_health_cmd grammar rules test_runner.c — execute + describe logic for both new commands --- src/bin/pgaftest/test_runner.c | 269 +++++ src/bin/pgaftest/test_spec.h | 26 + src/bin/pgaftest/test_spec_parse.c | 1722 +++++++++++++++------------- src/bin/pgaftest/test_spec_parse.y | 47 + src/bin/pgaftest/test_spec_scan.l | 5 + 5 files changed, 1245 insertions(+), 824 deletions(-) diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index 675c012e2..899e513dd 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -3154,6 +3154,260 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) return true; } + case CMD_NODE_ACTIVE: + { + /* + * Monitor node_active protocol test. + * + * Parse the raw block: "node2 reported: secondary lsn: 0/5A0 + * tli: 1 pgrunning: true" + * and the expect block: "assigned: secondary" + * + * Then: + * 1. Look up node_id from pgautofailover.node. + * 2. Call pgautofailover.node_active(...) on the monitor. + * 3. Assert the returned assigned state matches nodeActiveExpected. + */ + char nodeName[64] = { 0 }; + char reported[64] = "secondary"; + char lsn[32] = "0/0"; + int tli = 1; + int pgrunning = 1; + + /* Parse raw block content into key-value pairs */ + { + char buf[sizeof(cmd->args)]; + strlcpy(buf, cmd->args, sizeof(buf)); + + /* First token before any ':' is the node name */ + char *p = buf; + while (*p == ' ' || *p == '\t') + { + p++; + } + char *nameEnd = p; + while (*nameEnd && *nameEnd != ' ' && *nameEnd != '\t') + { + nameEnd++; + } + size_t nameLen = nameEnd - p; + if (nameLen >= sizeof(nodeName)) + { + nameLen = sizeof(nodeName) - 1; + } + memcpy(nodeName, p, nameLen); + nodeName[nameLen] = '\0'; + p = nameEnd; + + /* Parse remaining key: value pairs */ + while (*p) + { + while (*p == ' ' || *p == '\t') + { + p++; + } + char *kstart = p; + while (*p && *p != ':') + { + p++; + } + if (*p != ':') + { + break; + } + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + { + p++; + } + char *vstart = p; + while (*p && *p != ' ' && *p != '\t' && *p != '\n') + { + p++; + } + if (*p) + { + *p++ = '\0'; + } + + /* trim trailing whitespace from key */ + char *kt = kstart + strlen(kstart) - 1; + while (kt >= kstart && (*kt == ' ' || *kt == '\t')) + { + *kt-- = '\0'; + } + + if (strcmp(kstart, "reported") == 0) + { + strlcpy(reported, vstart, sizeof(reported)); + } + else if (strcmp(kstart, "lsn") == 0) + { + strlcpy(lsn, vstart, sizeof(lsn)); + } + else if (strcmp(kstart, "tli") == 0) + { + tli = atoi(vstart); + } + else if (strcmp(kstart, "pgrunning") == 0) + { + pgrunning = (strcmp(vstart, "true") == 0 || + strcmp(vstart, "1") == 0) ? 1 : 0; + } + } + } + + /* Parse expected: "assigned: secondary" */ + char expectedState[64] = { 0 }; + { + const char *p = cmd->nodeActiveExpected; + while (*p == ' ' || *p == '\t') + { + p++; + } + if (strncmp(p, "assigned:", 9) == 0) + { + p += 9; + while (*p == ' ' || *p == '\t') + { + p++; + } + strlcpy(expectedState, p, sizeof(expectedState)); + + /* trim trailing whitespace */ + char *e = expectedState + strlen(expectedState) - 1; + while (e >= expectedState && (*e == ' ' || *e == '\t' || *e == '\n')) + { + *e-- = '\0'; + } + } + } + + if (nodeName[0] == '\0' || expectedState[0] == '\0') + { + sformat(errBuf, errLen, + "node_active: failed to parse command " + "(args=%s expect=%s)", + cmd->args, cmd->nodeActiveExpected); + return false; + } + + log_info(" node_active: node=%s reported=%s lsn=%s tli=%d " + "pgrunning=%s expect assigned=%s", + nodeName, reported, lsn, tli, + pgrunning ? "true" : "false", expectedState); + + /* + * Step 1: resolve node_id + group_id from the monitor. + */ + char lookupSql[512]; + char nodeInfo[256] = { 0 }; + sformat(lookupSql, sizeof(lookupSql), + "SELECT nodeid || '|' || groupid " + "FROM pgautofailover.node " + "WHERE nodename = '%s' LIMIT 1", + nodeName); + + if (!exec_sql_on_service(r, "monitor", + lookupSql, nodeInfo, sizeof(nodeInfo))) + { + sformat(errBuf, errLen, + "node_active: could not look up node '%s' on monitor", + nodeName); + return false; + } + + /* strip trailing newline */ + char *nl = strchr(nodeInfo, '\n'); + if (nl) + { + *nl = '\0'; + } + + long long nodeId = 0; + int groupId = 0; + if (sscanf(nodeInfo, "%lld|%d", &nodeId, &groupId) != 2) + { + sformat(errBuf, errLen, + "node_active: unexpected node lookup result: '%s'", + nodeInfo); + return false; + } + + /* + * Step 2: call pgautofailover.node_active() and capture the + * assigned_group_state column. + */ + char callSql[1024]; + sformat(callSql, sizeof(callSql), + "SELECT assigned_group_state " + "FROM pgautofailover.node_active(" + "'default', %lld, %d, '%s', %s, %d, '%s', '')", + nodeId, groupId, + reported, + pgrunning ? "true" : "false", + tli, lsn); + + char assignedState[256] = { 0 }; + if (!exec_sql_on_service(r, "monitor", + callSql, assignedState, sizeof(assignedState))) + { + sformat(errBuf, errLen, + "node_active: call failed for node '%s': %s", + nodeName, assignedState); + return false; + } + + /* strip trailing whitespace */ + nl = assignedState + strlen(assignedState); + while (nl > assignedState && + (nl[-1] == '\n' || nl[-1] == '\r' || nl[-1] == ' ')) + { + *--nl = '\0'; + } + + if (strcmp(assignedState, expectedState) != 0) + { + sformat(errBuf, errLen, + "node_active: expected assigned='%s', got '%s'", + expectedState, assignedState); + return false; + } + return true; + } + + case CMD_MARK_HEALTH: + { + /* + * mark healthy/unhealthy: + * + * Directly update the health column in pgautofailover.node on the + * monitor. health=1 means GOOD, health=-1 means BAD. + */ + int healthValue = cmd->markHealthy ? 1 : -1; + char updateSql[512]; + sformat(updateSql, sizeof(updateSql), + "UPDATE pgautofailover.node " + "SET health = %d, healthchecktime = now() " + "WHERE nodename = '%s'", + healthValue, cmd->service); + + char out[256] = { 0 }; + if (!exec_sql_on_service(r, "monitor", updateSql, out, sizeof(out))) + { + sformat(errBuf, errLen, + "mark %s: UPDATE failed for node '%s': %s", + cmd->markHealthy ? "healthy" : "unhealthy", + cmd->service, out); + return false; + } + + log_info(" mark %s: node=%s", + cmd->markHealthy ? "healthy" : "unhealthy", + cmd->service); + return true; + } + case CMD_LOGS_CHECK: { /* @@ -3534,6 +3788,21 @@ cmd_label(const TestCmd *cmd, char *buf, int len) break; } + case CMD_NODE_ACTIVE: + { + sformat(buf, len, "node_active { %s } expect { %s }", + cmd->args, cmd->nodeActiveExpected); + break; + } + + case CMD_MARK_HEALTH: + { + sformat(buf, len, "mark %s: %s", + cmd->markHealthy ? "healthy" : "unhealthy", + cmd->service); + break; + } + default: { sformat(buf, len, "(unknown command %d)", cmd->kind); diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index 4446de914..0ec208184 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -162,6 +162,21 @@ typedef enum TestCmdKind CMD_SET_MONITOR, /* set monitor — switch active monitor service */ CMD_LOGS_CHECK, /* logs [not] — grep container logs */ CMD_COMPOSE_INJECT, /* compose inject : */ + + /* + * Monitor node_active protocol tests. + * + * node_active { reported: lsn: [tli: N] [pgrunning: bool] } + * expect { assigned: } + * + * Calls pgautofailover.node_active() on the monitor with the given + * parameters and asserts the returned assigned state. + * + * mark healthy: — set node health to GOOD (healthchecktime = now) + * mark unhealthy: — set node health to BAD (healthchecktime = now) + */ + CMD_NODE_ACTIVE, /* node_active { ... } expect { assigned: ... } */ + CMD_MARK_HEALTH, /* mark [un]healthy: */ } TestCmdKind; typedef struct TestCmd @@ -205,6 +220,17 @@ typedef struct TestCmd /* CMD_LOGS_CHECK */ bool logsNegate; /* true → assert pattern NOT found */ + /* CMD_NODE_ACTIVE */ + char nodeActiveName[64]; /* node name */ + char nodeActiveReported[64]; /* reported state string */ + char nodeActiveLsn[32]; /* LSN string, e.g. "0/5A0" */ + int nodeActiveTli; /* timeline, default 1 */ + bool nodeActivePgRunning; /* pg_is_running, default true */ + char nodeActiveExpected[64]; /* expected assigned state */ + + /* CMD_MARK_HEALTH */ + bool markHealthy; /* true → GOOD, false → BAD */ + struct TestCmd *next; } TestCmd; diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index 2595cab42..ee3af898c 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -167,11 +167,15 @@ enum yytokentype T_NOT = 355, T_CONTAINS = 356, T_MATCHES = 357, - T_INTEGER = 358, - T_IDENT = 359, - T_STRING = 360, - T_BLOCK = 361, - T_SHELL_ARGS = 362 + T_NODE_ACTIVE = 358, + T_MARK = 359, + T_HEALTHY = 360, + T_UNHEALTHY = 361, + T_INTEGER = 362, + T_IDENT = 363, + T_STRING = 364, + T_BLOCK = 365, + T_SHELL_ARGS = 366 }; #endif @@ -276,11 +280,15 @@ enum yytokentype #define T_NOT 355 #define T_CONTAINS 356 #define T_MATCHES 357 -#define T_INTEGER 358 -#define T_IDENT 359 -#define T_STRING 360 -#define T_BLOCK 361 -#define T_SHELL_ARGS 362 +#define T_NODE_ACTIVE 358 +#define T_MARK 359 +#define T_HEALTHY 360 +#define T_UNHEALTHY 361 +#define T_INTEGER 362 +#define T_IDENT 363 +#define T_STRING 364 +#define T_BLOCK 365 +#define T_SHELL_ARGS 366 /* Copy the first part of user declarations. */ @@ -325,8 +333,8 @@ static TestSpec *current_spec = NULL; static void yyerror(const char *msg) { - fprintf(/* IGNORE-BANNED */ stderr, "pgaftest: parse error at line %d: %s\n", - pgaf_line_number, msg); + fprintf(stderr, "pgaftest: parse error at line %d: %s\n", + pgaf_line_number, msg); exit(1); } @@ -438,7 +446,7 @@ expand_tuple_expect(char *buf, int buflen) } if (l > 0) { - memcpy(tmp + pos, row, l); /* IGNORE-BANNED */ + memcpy(tmp + pos, row, l); pos += l; } tmp[pos] = '\0'; @@ -447,7 +455,7 @@ expand_tuple_expect(char *buf, int buflen) if (!first) { - strlcpy(buf, tmp, buflen); + strncpy(buf, tmp, buflen - 1); } } @@ -515,7 +523,7 @@ typedef union YYSTYPE } /* Line 193 of yacc.c. */ -#line 461 "test_spec_parse.c" +#line 469 "test_spec_parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -527,7 +535,7 @@ YYSTYPE; /* Line 216 of yacc.c. */ -#line 474 "test_spec_parse.c" +#line 482 "test_spec_parse.c" #ifdef short # undef short @@ -746,23 +754,23 @@ union yyalloc #define YYFINAL 21 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 523 +#define YYLAST 581 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 108 +#define YYNTOKENS 113 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 62 +#define YYNNTS 64 /* YYNRULES -- Number of rules. */ -#define YYNRULES 193 +#define YYNRULES 198 /* YYNRULES -- Number of states. */ -#define YYNSTATES 312 +#define YYNSTATES 325 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 362 +#define YYMAXUTOK 366 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -775,7 +783,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -806,7 +814,7 @@ static const yytype_uint8 yytranslate[] = 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 + 105, 106, 107, 108, 109, 110, 111 }; #if YYDEBUG @@ -825,106 +833,108 @@ static const yytype_uint16 yyprhs[] = 185, 188, 191, 194, 197, 200, 203, 206, 209, 213, 217, 220, 223, 227, 231, 232, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, - 265, 268, 272, 275, 279, 282, 284, 286, 288, 293, - 298, 300, 304, 305, 308, 310, 312, 316, 320, 321, - 331, 332, 342, 350, 358, 364, 370, 377, 379, 381, - 385, 389, 390, 393, 396, 401, 402, 405, 409, 416, - 423, 430, 437, 441, 444, 447, 451, 455, 458, 460, - 464, 468, 472, 475, 478, 482, 486, 490, 495, 499, - 503, 504, 510, 516, 520, 525, 531, 536, 542, 545, - 546, 549, 551, 553, 555, 557, 559, 561, 563, 565, - 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, - 587, 589, 591, 593 + 263, 265, 269, 272, 276, 279, 283, 286, 288, 290, + 292, 297, 302, 304, 308, 309, 312, 314, 316, 320, + 324, 325, 335, 336, 346, 354, 362, 368, 374, 381, + 383, 385, 389, 393, 394, 397, 400, 405, 406, 409, + 413, 420, 427, 434, 441, 445, 448, 451, 455, 459, + 462, 464, 468, 472, 476, 479, 482, 486, 490, 494, + 499, 503, 507, 508, 514, 520, 524, 529, 535, 540, + 546, 551, 556, 561, 564, 565, 568, 570, 572, 574, + 576, 578, 580, 582, 584, 586, 588, 590, 592, 594, + 596, 598, 600, 602, 604, 606, 608, 610, 612 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 109, 0, -1, 110, -1, 109, 110, -1, 111, -1, - 133, -1, 134, -1, 135, -1, 166, -1, -1, 3, - 91, 112, 113, 92, -1, -1, 113, 114, -1, 115, - -1, 116, -1, 118, -1, 119, -1, 117, -1, 120, - -1, 40, -1, 4, -1, 4, 36, 104, -1, 4, - 14, 104, -1, 4, 32, 103, -1, 4, 33, 105, - -1, 4, 104, 24, 25, -1, 4, 104, 27, 84, - -1, 4, 104, 24, 25, 33, 105, -1, 13, 105, - -1, 13, 104, -1, 39, 104, -1, 39, 105, -1, - 15, 104, -1, 16, 104, -1, 17, 104, -1, -1, - 18, 121, 122, 91, 125, 92, -1, -1, 122, 124, - -1, 104, -1, 105, -1, 16, -1, 4, -1, 5, - -1, 123, -1, 19, 103, -1, -1, 125, 128, -1, - 104, -1, 4, -1, -1, -1, 126, 127, 129, 131, - -1, -1, 5, 104, 127, 130, 91, 131, 92, -1, - -1, 131, 132, -1, 20, -1, 21, -1, 22, -1, + 114, 0, -1, 115, -1, 114, 115, -1, 116, -1, + 138, -1, 139, -1, 140, -1, 173, -1, -1, 3, + 91, 117, 118, 92, -1, -1, 118, 119, -1, 120, + -1, 121, -1, 123, -1, 124, -1, 122, -1, 125, + -1, 40, -1, 4, -1, 4, 36, 108, -1, 4, + 14, 108, -1, 4, 32, 107, -1, 4, 33, 109, + -1, 4, 108, 24, 25, -1, 4, 108, 27, 84, + -1, 4, 108, 24, 25, 33, 109, -1, 13, 109, + -1, 13, 108, -1, 39, 108, -1, 39, 109, -1, + 15, 108, -1, 16, 108, -1, 17, 108, -1, -1, + 18, 126, 127, 91, 130, 92, -1, -1, 127, 129, + -1, 108, -1, 109, -1, 16, -1, 4, -1, 5, + -1, 128, -1, 19, 107, -1, -1, 130, 133, -1, + 108, -1, 4, -1, -1, -1, 131, 132, 134, 136, + -1, -1, 5, 108, 132, 135, 91, 136, 92, -1, + -1, 136, 137, -1, 20, -1, 21, -1, 22, -1, 23, -1, 25, -1, 24, 25, -1, 24, 26, -1, - 26, -1, 29, -1, 30, -1, 31, 103, -1, 90, - 103, -1, 32, 103, -1, 35, 104, -1, 36, 104, - -1, 15, 104, -1, 16, 104, -1, 17, 104, -1, - 37, 104, -1, 38, 105, -1, 34, 105, -1, 28, - 104, 104, -1, 28, 104, 105, -1, 8, 136, -1, - 9, 136, -1, 10, 169, 136, -1, 91, 137, 92, - -1, -1, 137, 138, -1, 139, -1, 145, -1, 152, - -1, 153, -1, 154, -1, 155, -1, 157, -1, 158, - -1, 159, -1, 160, -1, 163, -1, 164, -1, 165, - -1, 62, 104, 107, -1, 62, 104, -1, 63, 104, - 107, -1, 63, 104, -1, 64, 104, 107, -1, 64, - 104, -1, 64, -1, 12, -1, 69, -1, 104, 87, - 140, 168, -1, 104, 87, 140, 104, -1, 141, -1, - 142, 68, 141, -1, -1, 97, 144, -1, 168, -1, - 104, -1, 144, 93, 168, -1, 144, 93, 104, -1, - -1, 65, 66, 104, 87, 140, 168, 146, 143, 151, - -1, -1, 65, 66, 104, 87, 140, 104, 147, 143, - 151, -1, 65, 66, 104, 88, 140, 168, 151, -1, - 65, 66, 104, 88, 140, 104, 151, -1, 65, 66, - 104, 84, 151, -1, 65, 66, 148, 149, 151, -1, - 65, 66, 141, 68, 142, 151, -1, 168, -1, 104, - -1, 148, 93, 168, -1, 148, 93, 104, -1, -1, - 89, 150, -1, 90, 103, -1, 150, 93, 90, 103, - -1, -1, 67, 103, -1, 70, 67, 103, -1, 71, - 104, 87, 140, 168, 151, -1, 71, 104, 87, 140, - 104, 151, -1, 71, 104, 88, 140, 168, 151, -1, - 71, 104, 88, 140, 104, 151, -1, 72, 104, 106, - -1, 73, 106, -1, 73, 74, -1, 73, 74, 104, - -1, 73, 74, 103, -1, 75, 156, -1, 104, -1, - 156, 93, 104, -1, 76, 77, 104, -1, 76, 78, - 104, -1, 79, 103, -1, 80, 81, -1, 80, 82, - 104, -1, 80, 83, 104, -1, 80, 85, 104, -1, - 80, 86, 104, 107, -1, 83, 94, 126, -1, 82, - 94, 126, -1, -1, 96, 162, 91, 137, 92, -1, - 71, 126, 95, 168, 161, -1, 98, 104, 104, -1, - 99, 104, 101, 105, -1, 99, 104, 100, 101, 105, - -1, 99, 104, 102, 105, -1, 99, 104, 100, 102, - 105, -1, 11, 167, -1, -1, 167, 169, -1, 41, - -1, 42, -1, 43, -1, 44, -1, 45, -1, 46, - -1, 47, -1, 48, -1, 49, -1, 50, -1, 51, - -1, 52, -1, 53, -1, 54, -1, 55, -1, 56, - -1, 57, -1, 58, -1, 59, -1, 60, -1, 61, - -1, 104, -1, 105, -1 + 26, -1, 29, -1, 30, -1, 31, 107, -1, 90, + 107, -1, 32, 107, -1, 35, 108, -1, 36, 108, + -1, 15, 108, -1, 16, 108, -1, 17, 108, -1, + 37, 108, -1, 38, 109, -1, 34, 109, -1, 28, + 108, 108, -1, 28, 108, 109, -1, 8, 141, -1, + 9, 141, -1, 10, 176, 141, -1, 91, 142, 92, + -1, -1, 142, 143, -1, 144, -1, 150, -1, 157, + -1, 158, -1, 159, -1, 160, -1, 162, -1, 163, + -1, 164, -1, 165, -1, 168, -1, 169, -1, 170, + -1, 171, -1, 172, -1, 62, 108, 111, -1, 62, + 108, -1, 63, 108, 111, -1, 63, 108, -1, 64, + 108, 111, -1, 64, 108, -1, 64, -1, 12, -1, + 69, -1, 108, 87, 145, 175, -1, 108, 87, 145, + 108, -1, 146, -1, 147, 68, 146, -1, -1, 97, + 149, -1, 175, -1, 108, -1, 149, 93, 175, -1, + 149, 93, 108, -1, -1, 65, 66, 108, 87, 145, + 175, 151, 148, 156, -1, -1, 65, 66, 108, 87, + 145, 108, 152, 148, 156, -1, 65, 66, 108, 88, + 145, 175, 156, -1, 65, 66, 108, 88, 145, 108, + 156, -1, 65, 66, 108, 84, 156, -1, 65, 66, + 153, 154, 156, -1, 65, 66, 146, 68, 147, 156, + -1, 175, -1, 108, -1, 153, 93, 175, -1, 153, + 93, 108, -1, -1, 89, 155, -1, 90, 107, -1, + 155, 93, 90, 107, -1, -1, 67, 107, -1, 70, + 67, 107, -1, 71, 108, 87, 145, 175, 156, -1, + 71, 108, 87, 145, 108, 156, -1, 71, 108, 88, + 145, 175, 156, -1, 71, 108, 88, 145, 108, 156, + -1, 72, 108, 110, -1, 73, 110, -1, 73, 74, + -1, 73, 74, 108, -1, 73, 74, 107, -1, 75, + 161, -1, 108, -1, 161, 93, 108, -1, 76, 77, + 108, -1, 76, 78, 108, -1, 79, 107, -1, 80, + 81, -1, 80, 82, 108, -1, 80, 83, 108, -1, + 80, 85, 108, -1, 80, 86, 108, 111, -1, 83, + 94, 131, -1, 82, 94, 131, -1, -1, 96, 167, + 91, 142, 92, -1, 71, 131, 95, 175, 166, -1, + 98, 108, 108, -1, 99, 108, 101, 109, -1, 99, + 108, 100, 101, 109, -1, 99, 108, 102, 109, -1, + 99, 108, 100, 102, 109, -1, 103, 110, 73, 110, + -1, 104, 105, 112, 108, -1, 104, 106, 112, 108, + -1, 11, 174, -1, -1, 174, 176, -1, 41, -1, + 42, -1, 43, -1, 44, -1, 45, -1, 46, -1, + 47, -1, 48, -1, 49, -1, 50, -1, 51, -1, + 52, -1, 53, -1, 54, -1, 55, -1, 56, -1, + 57, -1, 58, -1, 59, -1, 60, -1, 61, -1, + 108, -1, 109, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 211, 211, 212, 216, 217, 218, 219, 220, 233, - 232, 242, 244, 248, 249, 250, 251, 252, 253, 254, - 267, 271, 278, 285, 291, 298, 305, 312, 325, 331, - 341, 347, 357, 367, 373, 384, 383, 400, 402, 411, - 412, 413, 414, 415, 419, 424, 430, 432, 451, 452, - 461, 478, 477, 485, 484, 492, 494, 498, 503, 508, - 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, - 552, 558, 564, 569, 574, 579, 587, 593, 599, 613, - 634, 641, 652, 670, 685, 688, 696, 697, 698, 699, - 700, 701, 702, 703, 704, 705, 706, 707, 708, 722, - 729, 735, 742, 748, 756, 762, 789, 789, 800, 815, - 833, 834, 849, 851, 855, 863, 871, 878, 890, 889, - 901, 900, 911, 920, 929, 936, 950, 965, 971, 978, - 984, 997, 999, 1003, 1008, 1016, 1017, 1018, 1029, 1037, - 1045, 1053, 1071, 1086, 1093, 1097, 1103, 1116, 1124, 1132, - 1147, 1153, 1166, 1180, 1184, 1190, 1196, 1222, 1256, 1262, - 1279, 1279, 1284, 1303, 1328, 1337, 1346, 1355, 1371, 1374, - 1376, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, - 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, - 1417, 1418, 1426, 1427 + 0, 213, 213, 214, 218, 219, 220, 221, 222, 235, + 234, 244, 246, 250, 251, 252, 253, 254, 255, 256, + 269, 273, 280, 287, 293, 300, 307, 314, 327, 333, + 343, 349, 359, 369, 375, 386, 385, 402, 404, 413, + 414, 415, 416, 417, 421, 426, 432, 434, 453, 454, + 463, 480, 479, 487, 486, 494, 496, 500, 505, 510, + 514, 518, 522, 526, 530, 534, 538, 542, 546, 550, + 554, 560, 566, 571, 576, 581, 589, 595, 601, 615, + 636, 643, 654, 672, 687, 690, 698, 699, 700, 701, + 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, + 712, 726, 733, 739, 746, 752, 760, 766, 793, 793, + 804, 819, 837, 838, 853, 855, 859, 867, 875, 882, + 894, 893, 905, 904, 915, 924, 933, 940, 954, 969, + 975, 982, 988, 1001, 1003, 1007, 1012, 1020, 1021, 1022, + 1033, 1041, 1049, 1057, 1075, 1090, 1097, 1101, 1107, 1120, + 1128, 1136, 1151, 1157, 1170, 1184, 1188, 1194, 1200, 1226, + 1260, 1266, 1283, 1283, 1288, 1307, 1332, 1341, 1350, 1359, + 1380, 1397, 1404, 1418, 1421, 1423, 1445, 1446, 1447, 1448, + 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, + 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1473, 1474 }; #endif @@ -956,9 +966,10 @@ static const char *const yytname[] = "T_COMPOSE", "T_DOWN", "T_START", "T_STOP", "T_STOPPED", "T_KILL", "T_INJECT", "T_STATE", "T_ASSIGNED_STATE", "T_IN", "T_GROUP", "T_LBRACE", "T_RBRACE", "T_COMMA", "T_POSTGRES", "T_STAYS", "T_WHILE", "T_THROUGH", - "T_SET", "T_LOGS", "T_NOT", "T_CONTAINS", "T_MATCHES", "T_INTEGER", - "T_IDENT", "T_STRING", "T_BLOCK", "T_SHELL_ARGS", "$accept", "spec", - "spec_item", "cluster_block", "@1", "cluster_item_list", "cluster_item", + "T_SET", "T_LOGS", "T_NOT", "T_CONTAINS", "T_MATCHES", "T_NODE_ACTIVE", + "T_MARK", "T_HEALTHY", "T_UNHEALTHY", "T_INTEGER", "T_IDENT", "T_STRING", + "T_BLOCK", "T_SHELL_ARGS", "':'", "$accept", "spec", "spec_item", + "cluster_block", "@1", "cluster_item_list", "cluster_item", "monitor_line", "image_line", "extension_version_line", "ssl_line", "auth_line", "formation_block", "@2", "formation_opt_list", "bare_name", "formation_opt", "node_list", "node_name", "init_node_slot", "node_line", @@ -970,7 +981,8 @@ static const char *const yytname[] = "assert_cmd", "sql_cmd", "expect_cmd", "promote_cmd", "promote_list", "network_cmd", "sleep_cmd", "compose_cmd", "postgres_ctl_cmd", "while_body", "@7", "stays_while_cmd", "set_monitor_cmd", "logs_cmd", - "sequence_block", "sequence_names", "fsm_state", "ident_or_string", 0 + "node_active_cmd", "mark_health_cmd", "sequence_block", "sequence_names", + "fsm_state", "ident_or_string", 0 }; #endif @@ -990,33 +1002,34 @@ static const yytype_uint16 yytoknum[] = 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362 + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 108, 109, 109, 110, 110, 110, 110, 110, 112, - 111, 113, 113, 114, 114, 114, 114, 114, 114, 114, - 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, - 117, 117, 118, 119, 119, 121, 120, 122, 122, 123, - 123, 123, 123, 123, 124, 124, 125, 125, 126, 126, - 127, 129, 128, 130, 128, 131, 131, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 133, 134, 135, 136, 137, 137, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, - 139, 139, 139, 139, 139, 139, 140, 140, 141, 141, - 142, 142, 143, 143, 144, 144, 144, 144, 146, 145, - 147, 145, 145, 145, 145, 145, 145, 148, 148, 148, - 148, 149, 149, 150, 150, 151, 151, 151, 152, 152, - 152, 152, 153, 154, 154, 154, 154, 155, 156, 156, - 157, 157, 158, 159, 159, 159, 159, 159, 160, 160, - 162, 161, 163, 164, 165, 165, 165, 165, 166, 167, - 167, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 169, 169 + 0, 113, 114, 114, 115, 115, 115, 115, 115, 117, + 116, 118, 118, 119, 119, 119, 119, 119, 119, 119, + 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, + 122, 122, 123, 124, 124, 126, 125, 127, 127, 128, + 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, + 132, 134, 133, 135, 133, 136, 136, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 138, 139, 140, 141, 142, 142, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 144, 144, 144, 144, 144, 144, 144, 145, 145, + 146, 146, 147, 147, 148, 148, 149, 149, 149, 149, + 151, 150, 152, 150, 150, 150, 150, 150, 150, 153, + 153, 153, 153, 154, 154, 155, 155, 156, 156, 156, + 157, 157, 157, 157, 158, 159, 159, 159, 159, 160, + 161, 161, 162, 162, 163, 164, 164, 164, 164, 164, + 165, 165, 167, 166, 168, 169, 170, 170, 170, 170, + 171, 172, 172, 173, 174, 174, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 176, 176 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1031,17 +1044,17 @@ static const yytype_uint8 yyr2[] = 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, 0, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 2, 3, 2, 3, 2, 1, 1, 1, 4, 4, - 1, 3, 0, 2, 1, 1, 3, 3, 0, 9, - 0, 9, 7, 7, 5, 5, 6, 1, 1, 3, - 3, 0, 2, 2, 4, 0, 2, 3, 6, 6, - 6, 6, 3, 2, 2, 3, 3, 2, 1, 3, - 3, 3, 2, 2, 3, 3, 3, 4, 3, 3, - 0, 5, 5, 3, 4, 5, 4, 5, 2, 0, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1 + 1, 3, 2, 3, 2, 3, 2, 1, 1, 1, + 4, 4, 1, 3, 0, 2, 1, 1, 3, 3, + 0, 9, 0, 9, 7, 7, 5, 5, 6, 1, + 1, 3, 3, 0, 2, 2, 4, 0, 2, 3, + 6, 6, 6, 6, 3, 2, 2, 3, 3, 2, + 1, 3, 3, 3, 2, 2, 3, 3, 3, 4, + 3, 3, 0, 5, 5, 3, 4, 5, 4, 5, + 4, 4, 4, 2, 0, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1049,258 +1062,273 @@ static const yytype_uint8 yyr2[] = * means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 0, 169, 0, 2, 4, 5, - 6, 7, 8, 9, 84, 80, 81, 192, 193, 0, - 168, 1, 3, 11, 0, 82, 170, 0, 0, 0, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 83, 0, 0, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 20, 0, - 0, 0, 0, 35, 0, 19, 10, 12, 13, 14, - 17, 15, 16, 18, 100, 102, 104, 0, 49, 48, - 0, 0, 144, 143, 148, 147, 0, 0, 152, 153, + 0, 0, 0, 0, 0, 174, 0, 2, 4, 5, + 6, 7, 8, 9, 84, 80, 81, 197, 198, 0, + 173, 1, 3, 11, 0, 82, 175, 0, 0, 0, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 83, 0, 0, 0, 0, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 20, 0, 0, 0, 0, 35, 0, 19, + 10, 12, 13, 14, 17, 15, 16, 18, 102, 104, + 106, 0, 49, 48, 0, 0, 146, 145, 150, 149, + 0, 0, 154, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 28, 32, 33, 34, 37, 30, - 31, 99, 101, 103, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 128, 0, 131, 127, 0, - 0, 0, 142, 146, 145, 0, 150, 151, 154, 155, - 156, 0, 48, 159, 158, 163, 0, 0, 0, 22, - 23, 24, 21, 0, 0, 0, 135, 0, 0, 0, - 0, 0, 135, 106, 107, 0, 0, 0, 149, 157, - 0, 0, 164, 166, 25, 26, 42, 43, 41, 0, - 46, 39, 40, 44, 38, 0, 0, 124, 0, 0, - 0, 110, 135, 0, 132, 130, 129, 125, 135, 135, - 135, 135, 160, 162, 165, 167, 0, 45, 0, 136, - 0, 120, 118, 135, 135, 0, 0, 126, 133, 0, - 139, 138, 141, 140, 0, 27, 0, 36, 50, 47, - 137, 112, 112, 123, 122, 0, 111, 0, 84, 50, - 51, 0, 135, 135, 109, 108, 134, 0, 53, 55, - 115, 113, 114, 121, 119, 161, 0, 52, 0, 55, - 0, 0, 0, 57, 58, 59, 60, 0, 61, 64, - 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, - 0, 56, 117, 116, 0, 72, 73, 74, 62, 63, - 0, 67, 69, 77, 70, 71, 75, 76, 68, 54, - 78, 79 + 29, 28, 32, 33, 34, 37, 30, 31, 101, 103, + 105, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 130, 0, 133, 129, 0, 0, 0, 144, + 148, 147, 0, 152, 153, 156, 157, 158, 0, 48, + 161, 160, 165, 0, 0, 0, 0, 0, 0, 22, + 23, 24, 21, 0, 0, 0, 137, 0, 0, 0, + 0, 0, 137, 108, 109, 0, 0, 0, 151, 159, + 0, 0, 166, 168, 170, 171, 172, 25, 26, 42, + 43, 41, 0, 46, 39, 40, 44, 38, 0, 0, + 126, 0, 0, 0, 112, 137, 0, 134, 132, 131, + 127, 137, 137, 137, 137, 162, 164, 167, 169, 0, + 45, 0, 138, 0, 122, 120, 137, 137, 0, 0, + 128, 135, 0, 141, 140, 143, 142, 0, 27, 0, + 36, 50, 47, 139, 114, 114, 125, 124, 0, 113, + 0, 84, 50, 51, 0, 137, 137, 111, 110, 136, + 0, 53, 55, 117, 115, 116, 123, 121, 163, 0, + 52, 0, 55, 0, 0, 0, 57, 58, 59, 60, + 0, 61, 64, 0, 65, 66, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 119, 118, 0, 72, 73, + 74, 62, 63, 0, 67, 69, 77, 70, 71, 75, + 76, 68, 54, 78, 79 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 6, 7, 8, 23, 27, 67, 68, 69, 70, - 71, 72, 73, 108, 165, 193, 194, 218, 80, 250, - 239, 259, 266, 267, 291, 9, 10, 11, 15, 24, - 44, 45, 175, 136, 202, 252, 261, 46, 242, 241, - 137, 172, 204, 197, 47, 48, 49, 50, 85, 51, - 52, 53, 54, 213, 234, 55, 56, 57, 12, 20, - 138, 19 + -1, 6, 7, 8, 23, 27, 71, 72, 73, 74, + 75, 76, 77, 115, 175, 206, 207, 231, 84, 263, + 252, 272, 279, 280, 304, 9, 10, 11, 15, 24, + 46, 47, 185, 143, 215, 265, 274, 48, 255, 254, + 144, 182, 217, 210, 49, 50, 51, 52, 89, 53, + 54, 55, 56, 226, 247, 57, 58, 59, 60, 61, + 12, 20, 145, 19 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing * STATE-NUM. */ -#define YYPACT_NINF -160 +#define YYPACT_NINF -171 static const yytype_int16 yypact[] = { - 45, -76, -65, -65, -45, -160, 109, -160, -160, -160, - -160, -160, -160, -160, -160, -160, -160, -160, -160, -65, - -45, -160, -160, -160, 145, -160, -160, 6, -72, -64, - -57, -24, 3, -25, -62, -19, 24, -14, 47, 19, - 32, -160, -9, 27, -160, -160, -160, -160, -160, -160, - -160, -160, -160, -160, -160, -160, -160, -160, -5, 11, - 33, 53, 111, -160, 30, -160, -160, -160, -160, -160, - -160, -160, -160, -160, 106, 112, 126, 122, -160, 55, - 29, 128, 102, -160, -160, 58, 127, 131, -160, -160, - 132, 134, 135, 136, 4, 4, 137, 21, 138, 129, - 140, 142, 73, -160, -160, -160, -160, -160, -160, -160, - -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, - -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, - -160, -160, -160, -160, -160, -51, 244, -75, -160, 17, - 17, 440, -160, -160, -160, 213, -160, -160, -160, -160, - -160, 211, -160, -160, -160, -160, 110, 214, 215, -160, - -160, -160, -160, 296, 241, 1, 44, 17, 17, 224, - 239, 143, 44, -160, -160, 207, 228, 240, -160, -160, - 230, 232, -160, -160, 305, -160, -160, -160, -160, 236, - -160, -160, -160, -160, -160, 237, 274, -160, 249, 313, - 255, -160, 20, 242, 253, -160, -160, -160, 44, 44, - 44, 44, -160, -160, -160, -160, 243, -160, -1, -160, - 248, 276, 279, 44, 44, 17, 224, -160, -160, 262, - -160, -160, -160, -160, 327, -160, 315, -160, -160, -160, - -160, 323, 323, -160, -160, 334, -160, 318, -160, -160, - -160, 355, 44, 44, -160, -160, -160, 251, -160, -160, - -160, 329, -160, -160, -160, -160, 332, 124, 419, -160, - 320, 321, 322, -160, -160, -160, -160, 197, -160, -160, - 324, -160, -160, 326, 328, 325, 330, 331, 333, 335, - 336, -160, -160, -160, 46, -160, -160, -160, -160, -160, - 125, -160, -160, -160, -160, -160, -160, -160, -160, -160, - -160, -160 + 73, -47, -26, -26, -74, -171, 69, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, -171, -26, + -74, -171, -171, -171, 410, -171, -171, 7, -40, -38, + -21, 23, 3, -14, -55, -6, -35, -7, -25, 21, + 27, -171, -2, 19, 15, -31, -171, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -5, -17, 20, 34, 40, -171, -11, -171, + -171, -171, -171, -171, -171, -171, -171, -171, 46, 47, + 55, 137, -171, 17, 29, 62, 6, -171, -171, 33, + 91, 92, -171, -171, 93, 95, 96, 98, 4, 4, + 122, -52, 56, 90, 119, 124, 126, 125, 127, 12, + -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -58, 168, -72, -171, 2, 2, 520, -171, + -171, -171, 129, -171, -171, -171, -171, -171, 128, -171, + -171, -171, -171, 16, 131, 132, 133, 130, 134, -171, + -171, -171, -171, 219, 183, -1, -8, 2, 2, 160, + 179, 167, -8, -171, -171, 205, 235, 174, -171, -171, + 162, 163, -171, -171, -171, -171, -171, 240, -171, -171, + -171, -171, 190, -171, -171, -171, -171, -171, 191, 207, + -171, 273, 303, 212, -171, 18, 193, 208, -171, -171, + -171, -8, -8, -8, -8, -171, -171, -171, -171, 194, + -171, 1, -171, 195, 236, 237, -8, -8, 2, 160, + -171, -171, 216, -171, -171, -171, -171, 217, -171, 199, + -171, -171, -171, -171, 213, 213, -171, -171, 341, -171, + 202, -171, -171, -171, 371, -8, -8, -171, -171, -171, + 456, -171, -171, -171, 218, -171, -171, -171, -171, 221, + 139, 409, -171, 227, 228, 229, -171, -171, -171, -171, + 94, -171, -171, 230, -171, -171, 232, 233, 256, 234, + 258, 259, 260, 261, -171, -171, -171, 115, -171, -171, + -171, -171, -171, 14, -171, -171, -171, -171, -171, -171, + -171, -171, -171, -171, -171 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -160, -160, 421, -160, -160, -160, -160, -160, -160, -160, - -160, -160, -160, -160, -160, -160, -160, -160, -93, 183, - -160, -160, -160, 164, -160, -160, -160, -160, 22, 188, - -160, -160, -129, -153, -160, 199, -160, -160, -160, -160, - -160, -160, -160, -159, -160, -160, -160, -160, -160, -160, - -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, - -141, 422 + -171, -171, 335, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, -97, 108, + -171, -171, -171, 89, -171, -171, -171, -171, 13, 111, + -171, -171, -137, -166, -171, 118, -171, -171, -171, -171, + -171, -171, -171, -170, -171, -171, -171, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -148, 354 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If * positive, shift that token. If negative, reduce the rule which * number is the opposite. If zero, do what YYDEFACT says. * If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -110 +#define YYTABLE_NINF -112 static const yytype_int16 yytable[] = { - 177, 153, 154, 78, 236, 186, 187, 78, 78, 98, - 58, 176, 82, 207, 170, 13, 201, 188, 171, 59, - 189, 60, 61, 62, 63, 16, 14, 99, 100, 173, - 206, 101, 74, 166, 209, 211, 167, 168, 198, 199, - 75, 25, 77, 227, 83, 64, 65, 76, 1, 230, - 231, 232, 233, 2, 3, 4, 5, 222, 224, 17, - 18, 270, 271, 272, 243, 244, 273, 274, 275, 276, - 277, 278, 279, 246, 280, 281, 282, 283, 284, 81, - 285, 286, 287, 288, 289, 84, 174, 195, 226, 88, - 196, 237, 190, 263, 264, 96, 245, 163, 66, 102, - 164, 86, 87, 152, 255, 191, 192, 79, 152, 21, - 262, 195, 1, 94, 196, 103, 104, 2, 3, 4, - 5, 156, 157, 158, 141, 238, 95, 293, 89, 90, - 91, 97, 92, 93, 109, 110, 290, 105, 309, 270, - 271, 272, 139, 140, 273, 274, 275, 276, 277, 278, - 279, 145, 280, 281, 282, 283, 284, 106, 285, 286, - 287, 288, 289, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 143, 144, 28, 29, 30, - 31, 180, 181, 111, 290, 107, 32, 33, 34, 112, - 35, 36, 298, 299, 37, 38, 135, 39, 40, 310, - 311, 146, 160, 113, 142, 147, 148, 41, 149, 150, - 151, 155, 159, 42, 43, 161, 162, 205, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 208, 169, 28, 29, 30, 31, 178, 179, 182, - 183, 184, 32, 33, 34, 185, 35, 36, 200, 203, - 37, 38, 210, 39, 40, 214, 212, 215, 216, 217, - 219, 220, 225, 265, -109, 228, 229, -108, 235, 42, - 43, 240, 247, 221, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 223, 248, 249, - 251, 256, 268, 269, 295, 296, 297, 22, 300, 301, - 303, 302, 258, 294, 304, 305, 257, 306, 254, 308, - 307, 253, 26, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 187, 160, 161, 199, 200, 82, 249, 82, 82, 105, + 186, 62, 220, 214, 183, 201, 16, 180, 202, 86, + 63, 181, 64, 65, 66, 67, 176, 106, 107, 177, + 178, 108, 25, 219, 17, 18, 173, 222, 224, 174, + 211, 212, 90, 91, 13, 240, 68, 69, 163, 164, + 165, 243, 244, 245, 246, 87, 93, 94, 95, 208, + 96, 97, 209, 235, 237, 14, 256, 257, 78, 21, + 79, 184, 1, 259, 103, 104, 1, 2, 3, 4, + 5, 2, 3, 4, 5, 208, 239, 80, 209, 81, + 203, 110, 111, 250, 85, 276, 277, 116, 117, 70, + 92, 258, 88, 109, 146, 147, 100, 204, 205, 159, + 268, 83, 159, 150, 151, 98, 275, 190, 191, 311, + 312, 99, 323, 324, 148, 102, 152, 101, 112, 166, + 283, 284, 285, 306, 251, 286, 287, 288, 289, 290, + 291, 292, 113, 293, 294, 295, 296, 297, 114, 298, + 299, 300, 301, 302, 283, 284, 285, 118, 119, 286, + 287, 288, 289, 290, 291, 292, 120, 293, 294, 295, + 296, 297, 149, 298, 299, 300, 301, 302, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 292 + 133, 134, 135, 136, 137, 138, 139, 140, 141, 153, + 154, 155, 167, 156, 157, 303, 158, 322, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 303, + 162, 168, 169, 170, 171, 172, 179, 188, 195, 189, + 192, 193, 196, 194, 197, 142, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 198, 213, 216, + 225, 227, 228, 229, 233, 218, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 230, 232, 238, + 241, 242, 253, 248, -111, -110, 260, 262, 261, 269, + 264, 281, 282, 221, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 308, 309, 310, 313, 314, + 315, 22, 317, 223, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 316, 318, 319, 321, 320, + 271, 307, 270, 266, 26, 0, 0, 0, 0, 0, + 0, 234, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 0, 0, 0, 0, 0, 0, 0, + 0, 236, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 0, 28, 29, 30, 31, 0, 0, 0, 273, + 0, 32, 33, 34, 0, 35, 36, 0, 0, 37, + 38, 0, 39, 40, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 0, 0, 0, 0, 0, 42, 43, + 0, 0, 0, 44, 45, 0, 0, 305, 28, 29, + 30, 31, 0, 0, 0, 0, 0, 32, 33, 34, + 0, 35, 36, 0, 0, 37, 38, 0, 39, 40, + 0, 0, 0, 0, 0, 0, 0, 0, 278, 0, + 0, 0, 0, 0, 42, 43, 0, 0, 0, 44, + 45, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141 }; static const yytype_int16 yycheck[] = { - 141, 94, 95, 4, 5, 4, 5, 4, 4, 14, - 4, 140, 74, 172, 89, 91, 169, 16, 93, 13, - 19, 15, 16, 17, 18, 3, 91, 32, 33, 12, - 171, 36, 104, 84, 175, 176, 87, 88, 167, 168, - 104, 19, 66, 202, 106, 39, 40, 104, 3, 208, - 209, 210, 211, 8, 9, 10, 11, 198, 199, 104, - 105, 15, 16, 17, 223, 224, 20, 21, 22, 23, - 24, 25, 26, 226, 28, 29, 30, 31, 32, 104, - 34, 35, 36, 37, 38, 104, 69, 67, 68, 103, - 70, 92, 91, 252, 253, 104, 225, 24, 92, 104, - 27, 77, 78, 104, 245, 104, 105, 104, 104, 0, - 251, 67, 3, 94, 70, 104, 105, 8, 9, 10, - 11, 100, 101, 102, 95, 218, 94, 268, 81, 82, - 83, 104, 85, 86, 104, 105, 90, 104, 92, 15, - 16, 17, 87, 88, 20, 21, 22, 23, 24, 25, - 26, 93, 28, 29, 30, 31, 32, 104, 34, 35, - 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 103, 104, 62, 63, 64, - 65, 101, 102, 107, 90, 104, 71, 72, 73, 107, - 75, 76, 25, 26, 79, 80, 104, 82, 83, 104, - 105, 104, 103, 107, 106, 104, 104, 92, 104, 104, - 104, 104, 104, 98, 99, 105, 104, 104, 41, 42, + 148, 98, 99, 4, 5, 4, 5, 4, 4, 14, + 147, 4, 182, 179, 12, 16, 3, 89, 19, 74, + 13, 93, 15, 16, 17, 18, 84, 32, 33, 87, + 88, 36, 19, 181, 108, 109, 24, 185, 186, 27, + 177, 178, 77, 78, 91, 215, 39, 40, 100, 101, + 102, 221, 222, 223, 224, 110, 81, 82, 83, 67, + 85, 86, 70, 211, 212, 91, 236, 237, 108, 0, + 108, 69, 3, 239, 105, 106, 3, 8, 9, 10, + 11, 8, 9, 10, 11, 67, 68, 108, 70, 66, + 91, 108, 109, 92, 108, 265, 266, 108, 109, 92, + 107, 238, 108, 108, 87, 88, 108, 108, 109, 108, + 258, 108, 108, 107, 108, 94, 264, 101, 102, 25, + 26, 94, 108, 109, 95, 110, 93, 108, 108, 73, + 15, 16, 17, 281, 231, 20, 21, 22, 23, 24, + 25, 26, 108, 28, 29, 30, 31, 32, 108, 34, + 35, 36, 37, 38, 15, 16, 17, 111, 111, 20, + 21, 22, 23, 24, 25, 26, 111, 28, 29, 30, + 31, 32, 110, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 104, 68, 62, 63, 64, 65, 104, 107, 105, - 105, 25, 71, 72, 73, 84, 75, 76, 104, 90, - 79, 80, 104, 82, 83, 105, 96, 105, 33, 103, - 103, 67, 87, 92, 68, 103, 93, 68, 105, 98, - 99, 103, 90, 104, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 41, 42, 43, 44, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 108, + 108, 108, 112, 108, 108, 90, 108, 92, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 90, + 108, 112, 108, 107, 109, 108, 68, 108, 108, 111, + 109, 109, 108, 110, 25, 108, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 84, 108, 90, + 96, 109, 109, 33, 67, 108, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 104, 91, 104, - 97, 103, 93, 91, 104, 104, 104, 6, 104, 103, - 105, 103, 249, 269, 104, 104, 248, 104, 104, 103, - 105, 242, 20, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, + 55, 56, 57, 58, 59, 60, 61, 107, 107, 87, + 107, 93, 107, 109, 68, 68, 90, 108, 91, 107, + 97, 93, 91, 108, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 108, 108, 108, 108, 107, + 107, 6, 108, 108, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 109, 108, 108, 107, 109, + 262, 282, 261, 255, 20, -1, -1, -1, -1, -1, + -1, 108, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, + -1, 108, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 61, -1, 62, 63, 64, 65, -1, -1, -1, 108, + -1, 71, 72, 73, -1, 75, 76, -1, -1, 79, + 80, -1, 82, 83, -1, -1, -1, -1, -1, -1, + -1, -1, 92, -1, -1, -1, -1, -1, 98, 99, + -1, -1, -1, 103, 104, -1, -1, 108, 62, 63, + 64, 65, -1, -1, -1, -1, -1, 71, 72, 73, + -1, 75, 76, -1, -1, 79, 80, -1, 82, 83, + -1, -1, -1, -1, -1, -1, -1, -1, 92, -1, + -1, -1, -1, -1, 98, 99, -1, -1, -1, 103, + 104, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 104 + 60, 61 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing * symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 8, 9, 10, 11, 109, 110, 111, 133, - 134, 135, 166, 91, 91, 136, 136, 104, 105, 169, - 167, 0, 110, 112, 137, 136, 169, 113, 62, 63, + 0, 3, 8, 9, 10, 11, 114, 115, 116, 138, + 139, 140, 173, 91, 91, 141, 141, 108, 109, 176, + 174, 0, 115, 117, 142, 141, 176, 118, 62, 63, 64, 65, 71, 72, 73, 75, 76, 79, 80, 82, - 83, 92, 98, 99, 138, 139, 145, 152, 153, 154, - 155, 157, 158, 159, 160, 163, 164, 165, 4, 13, - 15, 16, 17, 18, 39, 40, 92, 114, 115, 116, - 117, 118, 119, 120, 104, 104, 104, 66, 4, 104, - 126, 104, 74, 106, 104, 156, 77, 78, 103, 81, - 82, 83, 85, 86, 94, 94, 104, 104, 14, 32, - 33, 36, 104, 104, 105, 104, 104, 104, 121, 104, - 105, 107, 107, 107, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 104, 141, 148, 168, 87, - 88, 95, 106, 103, 104, 93, 104, 104, 104, 104, - 104, 104, 104, 126, 126, 104, 100, 101, 102, 104, - 103, 105, 104, 24, 27, 122, 84, 87, 88, 68, - 89, 93, 149, 12, 69, 140, 140, 168, 104, 107, - 101, 102, 105, 105, 25, 84, 4, 5, 16, 19, - 91, 104, 105, 123, 124, 67, 70, 151, 140, 140, - 104, 141, 142, 90, 150, 104, 168, 151, 104, 168, - 104, 168, 96, 161, 105, 105, 33, 103, 125, 103, - 67, 104, 168, 104, 168, 87, 68, 151, 103, 93, - 151, 151, 151, 151, 162, 105, 5, 92, 126, 128, - 103, 147, 146, 151, 151, 140, 141, 90, 91, 104, - 127, 97, 143, 143, 104, 168, 103, 137, 127, 129, - 104, 144, 168, 151, 151, 92, 130, 131, 93, 91, - 15, 16, 17, 20, 21, 22, 23, 24, 25, 26, - 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, - 90, 132, 104, 168, 131, 104, 104, 104, 25, 26, - 104, 103, 103, 105, 104, 104, 104, 105, 103, 92, - 104, 105 + 83, 92, 98, 99, 103, 104, 143, 144, 150, 157, + 158, 159, 160, 162, 163, 164, 165, 168, 169, 170, + 171, 172, 4, 13, 15, 16, 17, 18, 39, 40, + 92, 119, 120, 121, 122, 123, 124, 125, 108, 108, + 108, 66, 4, 108, 131, 108, 74, 110, 108, 161, + 77, 78, 107, 81, 82, 83, 85, 86, 94, 94, + 108, 108, 110, 105, 106, 14, 32, 33, 36, 108, + 108, 109, 108, 108, 108, 126, 108, 109, 111, 111, + 111, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 108, 146, 153, 175, 87, 88, 95, 110, + 107, 108, 93, 108, 108, 108, 108, 108, 108, 108, + 131, 131, 108, 100, 101, 102, 73, 112, 112, 108, + 107, 109, 108, 24, 27, 127, 84, 87, 88, 68, + 89, 93, 154, 12, 69, 145, 145, 175, 108, 111, + 101, 102, 109, 109, 110, 108, 108, 25, 84, 4, + 5, 16, 19, 91, 108, 109, 128, 129, 67, 70, + 156, 145, 145, 108, 146, 147, 90, 155, 108, 175, + 156, 108, 175, 108, 175, 96, 166, 109, 109, 33, + 107, 130, 107, 67, 108, 175, 108, 175, 87, 68, + 156, 107, 93, 156, 156, 156, 156, 167, 109, 5, + 92, 131, 133, 107, 152, 151, 156, 156, 145, 146, + 90, 91, 108, 132, 97, 148, 148, 108, 175, 107, + 142, 132, 134, 108, 149, 175, 156, 156, 92, 135, + 136, 93, 91, 15, 16, 17, 20, 21, 22, 23, + 24, 25, 26, 28, 29, 30, 31, 32, 34, 35, + 36, 37, 38, 90, 137, 108, 175, 136, 108, 108, + 108, 25, 26, 108, 107, 107, 109, 108, 108, 108, + 109, 107, 92, 108, 109 }; #define yyerrok (yyerrstatus = 0) @@ -1376,9 +1404,9 @@ static const yytype_uint8 yystos[] = #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ - fprintf(/* IGNORE-BANNED */ File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) + fprintf(File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif @@ -1420,8 +1448,8 @@ static const yytype_uint8 yystos[] = /*--------------------------------. - | Print this symbol on YYOUTPUT. | - | `--------------------------------*/ +| Print this symbol on YYOUTPUT. | +| `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1458,8 +1486,8 @@ YYSTYPE const *const yyvaluep; /*--------------------------------. - | Print this symbol on YYOUTPUT. | - | `--------------------------------*/ +| Print this symbol on YYOUTPUT. | +| `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1485,9 +1513,9 @@ YYSTYPE const *const yyvaluep; } /*------------------------------------------------------------------. - | yy_stack_print -- Print the state stack from its BOTTOM up to its | - | TOP (included). | - | `------------------------------------------------------------------*/ +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +| `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1514,8 +1542,8 @@ yytype_int16 *top; /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - | `------------------------------------------------*/ +| Report that the YYRULE is going to be reduced. | +| `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1535,11 +1563,11 @@ int yyrule; /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf(stderr, " $%d = ", yyi + 1); /* IGNORE-BANNED */ + fprintf(stderr, " $%d = ", yyi + 1); yy_symbol_print(stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - fprintf(stderr, "\n"); /* IGNORE-BANNED */ + fprintf(stderr, "\n"); } } @@ -1680,13 +1708,11 @@ yytnamerr(char *yyres, const char *yystr) } case '"': - { if (yyres) { yyres[yyn] = '\0'; } return yyn; - } } } do_not_strip_quotes:; @@ -1826,8 +1852,8 @@ yysyntax_error(char *yyresult, int yystate, int yychar) /*-----------------------------------------------. - | Release the memory associated to this symbol. | - | `-----------------------------------------------*/ +| Release the memory associated to this symbol. | +| `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1886,8 +1912,8 @@ int yynerrs; /*----------. - | yyparse. | - | `----------*/ +| yyparse. | +| `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1976,8 +2002,8 @@ yyparse() goto yysetstate; /*------------------------------------------------------------. - | yynewstate -- Push a new state, which is found in yystate. | - | `------------------------------------------------------------*/ +| yynewstate -- Push a new state, which is found in yystate. | +| `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks @@ -2068,8 +2094,8 @@ yyparse() goto yybackup; /*-----------. - | yybackup. | - | `-----------*/ +| yybackup. | +| `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a @@ -2148,8 +2174,8 @@ yyparse() /*-----------------------------------------------------------. - | yydefault -- do the default action for the current state. | - | `-----------------------------------------------------------*/ +| yydefault -- do the default action for the current state. | +| `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) @@ -2160,8 +2186,8 @@ yyparse() /*-----------------------------. - | yyreduce -- Do a reduction. | - | `-----------------------------*/ +| yyreduce -- Do a reduction. | +| `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -2182,92 +2208,92 @@ yyparse() switch (yyn) { case 9: -#line 233 "test_spec_parse.y" +#line 235 "test_spec_parse.y" { strlcpy(current_spec->cluster.ssl, "self-signed", sizeof(current_spec->cluster.ssl)); strlcpy(current_spec->cluster.auth, "trust", sizeof(current_spec->cluster.auth)); - break; } + break; case 19: -#line 254 "test_spec_parse.y" +#line 256 "test_spec_parse.y" { current_spec->cluster.bindSource = true; - break; } + break; case 20: -#line 268 "test_spec_parse.y" +#line 270 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; - break; } + break; case 21: -#line 272 "test_spec_parse.y" +#line 274 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorDebianCluster, (yyvsp[(3) - (3)].str), sizeof(current_spec->cluster.monitorDebianCluster)); free((yyvsp[(3) - (3)].str)); - break; } + break; case 22: -#line 279 "test_spec_parse.y" +#line 281 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorImageTarget, (yyvsp[(3) - (3)].str), sizeof(current_spec->cluster.monitorImageTarget)); free((yyvsp[(3) - (3)].str)); - break; } + break; case 23: -#line 286 "test_spec_parse.y" +#line 288 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; /* monitor port not stored in TestCluster yet; ignore */ (void) (yyvsp[(3) - (3)].ival); - break; } + break; case 24: -#line 292 "test_spec_parse.y" +#line 294 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorPassword, (yyvsp[(3) - (3)].str), sizeof(current_spec->cluster.monitorPassword)); free((yyvsp[(3) - (3)].str)); - break; } + break; case 25: -#line 299 "test_spec_parse.y" +#line 301 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (4)].str), sizeof(current_spec->cluster.secondMonitorName)); current_spec->cluster.secondMonitorStopped = true; free((yyvsp[(2) - (4)].str)); - break; } + break; case 26: -#line 306 "test_spec_parse.y" +#line 308 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (4)].str), sizeof(current_spec->cluster.secondMonitorName)); current_spec->cluster.secondMonitorStopped = true; free((yyvsp[(2) - (4)].str)); - break; } + break; case 27: -#line 313 "test_spec_parse.y" +#line 315 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (6)].str), sizeof(current_spec->cluster.secondMonitorName)); @@ -2276,330 +2302,328 @@ yyparse() /* password for second monitor not yet stored */ free((yyvsp[(6) - (6)].str)); - break; } + break; case 28: -#line 326 "test_spec_parse.y" +#line 328 "test_spec_parse.y" { strlcpy(current_spec->cluster.image, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.image)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 29: -#line 332 "test_spec_parse.y" +#line 334 "test_spec_parse.y" { strlcpy(current_spec->cluster.image, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.image)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 30: -#line 342 "test_spec_parse.y" +#line 344 "test_spec_parse.y" { strlcpy(current_spec->cluster.extensionVersion, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.extensionVersion)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 31: -#line 348 "test_spec_parse.y" +#line 350 "test_spec_parse.y" { strlcpy(current_spec->cluster.extensionVersion, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.extensionVersion)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 32: -#line 358 "test_spec_parse.y" +#line 360 "test_spec_parse.y" { strlcpy(current_spec->cluster.ssl, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.ssl)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 33: -#line 368 "test_spec_parse.y" +#line 370 "test_spec_parse.y" { strlcpy(current_spec->cluster.auth, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.auth)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 34: -#line 374 "test_spec_parse.y" +#line 376 "test_spec_parse.y" { strlcpy(current_spec->cluster.auth, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.auth)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 35: -#line 384 "test_spec_parse.y" +#line 386 "test_spec_parse.y" { TestCluster *cl = ¤t_spec->cluster; if (cl->formationCount >= PGAF_MAX_FORMATIONS) { - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: too many formations (max %d)\n", - PGAF_MAX_FORMATIONS); + fprintf(stderr, "pgaftest: too many formations (max %d)\n", + PGAF_MAX_FORMATIONS); exit(1); } current_formation = &cl->formations[cl->formationCount++]; strlcpy(current_formation->name, "default", sizeof(current_formation->name)); current_formation->numSync = -1; - break; } + break; case 39: -#line 411 "test_spec_parse.y" +#line 413 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); - break; } + break; case 40: -#line 412 "test_spec_parse.y" +#line 414 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); - break; } + break; case 41: -#line 413 "test_spec_parse.y" +#line 415 "test_spec_parse.y" { (yyval.str) = strdup("auth"); - break; } + break; case 42: -#line 414 "test_spec_parse.y" +#line 416 "test_spec_parse.y" { (yyval.str) = strdup("monitor"); - break; } + break; case 43: -#line 415 "test_spec_parse.y" +#line 417 "test_spec_parse.y" { (yyval.str) = strdup("node"); - break; } + break; case 44: -#line 420 "test_spec_parse.y" +#line 422 "test_spec_parse.y" { strlcpy(current_formation->name, (yyvsp[(1) - (1)].str), sizeof(current_formation->name)); free((yyvsp[(1) - (1)].str)); - break; } + break; case 45: -#line 425 "test_spec_parse.y" +#line 427 "test_spec_parse.y" { current_formation->numSync = (yyvsp[(2) - (2)].ival); - break; } + break; case 48: -#line 451 "test_spec_parse.y" +#line 453 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); - break; } + break; case 49: -#line 452 "test_spec_parse.y" +#line 454 "test_spec_parse.y" { (yyval.str) = strdup("monitor"); - break; } + break; case 50: -#line 461 "test_spec_parse.y" +#line 463 "test_spec_parse.y" { if (current_formation->nodeCount >= PGAF_MAX_NODES) { - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: too many nodes in formation (max %d)\n", - PGAF_MAX_NODES); + fprintf(stderr, "pgaftest: too many nodes in formation (max %d)\n", + PGAF_MAX_NODES); exit(1); } current_node = ¤t_formation->nodes[current_formation->nodeCount++]; current_node->kind = NODE_KIND_STANDALONE; current_node->candidatePriority = 50; current_node->replicationQuorum = true; - break; } + break; case 51: -#line 478 "test_spec_parse.y" +#line 480 "test_spec_parse.y" { strlcpy(current_node->name, (yyvsp[(1) - (2)].str), sizeof(current_node->name)); free((yyvsp[(1) - (2)].str)); - break; } + break; case 53: -#line 485 "test_spec_parse.y" +#line 487 "test_spec_parse.y" { strlcpy(current_node->name, (yyvsp[(2) - (3)].str), sizeof(current_node->name)); free((yyvsp[(2) - (3)].str)); - break; } + break; case 57: -#line 499 "test_spec_parse.y" +#line 501 "test_spec_parse.y" { current_node->kind = NODE_KIND_CITUS_COORDINATOR; current_spec->cluster.withCitus = true; - break; } + break; case 58: -#line 504 "test_spec_parse.y" +#line 506 "test_spec_parse.y" { current_node->kind = NODE_KIND_CITUS_WORKER; current_spec->cluster.withCitus = true; - break; } + break; case 59: -#line 509 "test_spec_parse.y" +#line 511 "test_spec_parse.y" { current_node->replicationQuorum = false; - break; } + break; case 60: -#line 513 "test_spec_parse.y" +#line 515 "test_spec_parse.y" { current_node->noMonitor = true; - break; } + break; case 61: -#line 517 "test_spec_parse.y" +#line 519 "test_spec_parse.y" { current_node->launchDeferred = true; - break; } + break; case 62: -#line 521 "test_spec_parse.y" +#line 523 "test_spec_parse.y" { current_node->launchDeferred = true; - break; } + break; case 63: -#line 525 "test_spec_parse.y" +#line 527 "test_spec_parse.y" { current_node->launchDeferred = false; - break; } + break; case 64: -#line 529 "test_spec_parse.y" +#line 531 "test_spec_parse.y" { current_node->launchDeferred = false; - break; } + break; case 65: -#line 533 "test_spec_parse.y" +#line 535 "test_spec_parse.y" { current_node->listen = true; - break; } + break; case 66: -#line 537 "test_spec_parse.y" +#line 539 "test_spec_parse.y" { current_node->citusSecondary = true; - break; } + break; case 67: -#line 541 "test_spec_parse.y" +#line 543 "test_spec_parse.y" { current_node->candidatePriority = (yyvsp[(2) - (2)].ival); - break; } + break; case 68: -#line 545 "test_spec_parse.y" +#line 547 "test_spec_parse.y" { current_node->group = (yyvsp[(2) - (2)].ival); - break; } + break; case 69: -#line 549 "test_spec_parse.y" +#line 551 "test_spec_parse.y" { current_node->pgPort = (yyvsp[(2) - (2)].ival); - break; } + break; case 70: -#line 553 "test_spec_parse.y" +#line 555 "test_spec_parse.y" { strlcpy(current_node->citusClusterName, (yyvsp[(2) - (2)].str), sizeof(current_node->citusClusterName)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 71: -#line 559 "test_spec_parse.y" +#line 561 "test_spec_parse.y" { strlcpy(current_node->debianCluster, (yyvsp[(2) - (2)].str), sizeof(current_node->debianCluster)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 72: -#line 565 "test_spec_parse.y" +#line 567 "test_spec_parse.y" { strlcpy(current_node->ssl, (yyvsp[(2) - (2)].str), sizeof(current_node->ssl)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 73: -#line 570 "test_spec_parse.y" +#line 572 "test_spec_parse.y" { strlcpy(current_node->auth, (yyvsp[(2) - (2)].str), sizeof(current_node->auth)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 74: -#line 575 "test_spec_parse.y" +#line 577 "test_spec_parse.y" { strlcpy(current_node->auth, (yyvsp[(2) - (2)].str), sizeof(current_node->auth)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 75: -#line 580 "test_spec_parse.y" +#line 582 "test_spec_parse.y" { if (strcmp((yyvsp[(2) - (2)].str), "false") == 0 || strcmp((yyvsp[(2) - (2)].str), @@ -2612,29 +2636,29 @@ yyparse() current_node->replicationQuorum = true; } free((yyvsp[(2) - (2)].str)); - break; } + break; case 76: -#line 588 "test_spec_parse.y" +#line 590 "test_spec_parse.y" { strlcpy(current_node->replicationPassword, (yyvsp[(2) - (2)].str), sizeof(current_node->replicationPassword)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 77: -#line 594 "test_spec_parse.y" +#line 596 "test_spec_parse.y" { strlcpy(current_node->monitorPassword, (yyvsp[(2) - (2)].str), sizeof(current_node->monitorPassword)); free((yyvsp[(2) - (2)].str)); - break; } + break; case 78: -#line 600 "test_spec_parse.y" +#line 602 "test_spec_parse.y" { /* volume — adds a named Docker volume */ int vi = current_node->volumeCount; @@ -2648,11 +2672,11 @@ yyparse() } free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; case 79: -#line 614 "test_spec_parse.y" +#line 616 "test_spec_parse.y" { /* volume "/path/with spaces" */ int vi = current_node->volumeCount; @@ -2666,35 +2690,35 @@ yyparse() } free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; case 80: -#line 635 "test_spec_parse.y" +#line 637 "test_spec_parse.y" { current_spec->setup = (yyvsp[(2) - (2)].step); - break; } + break; case 81: -#line 642 "test_spec_parse.y" +#line 644 "test_spec_parse.y" { current_spec->teardown = (yyvsp[(2) - (2)].step); - break; } + break; case 82: -#line 653 "test_spec_parse.y" +#line 655 "test_spec_parse.y" { TestStep *s = (yyvsp[(3) - (3)].step); - strlcpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name)); + strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); free((yyvsp[(2) - (3)].str)); register_step(current_spec, s); - break; } + break; case 83: -#line 671 "test_spec_parse.y" +#line 673 "test_spec_parse.y" { /* post-process: CMD_SQL immediately before CMD_EXPECT_ERROR */ for (TestCmd *c = (yyvsp[(2) - (3)].step)->commands; c; c = c->next) @@ -2706,120 +2730,134 @@ yyparse() } } (yyval.step) = (yyvsp[(2) - (3)].step); - break; } + break; case 84: -#line 685 "test_spec_parse.y" +#line 687 "test_spec_parse.y" { (yyval.step) = make_step(""); - break; } + break; case 85: -#line 689 "test_spec_parse.y" +#line 691 "test_spec_parse.y" { if ((yyvsp[(2) - (2)].cmd)) { append_cmd((yyvsp[(1) - (2)].step), (yyvsp[(2) - (2)].cmd)); } (yyval.step) = (yyvsp[(1) - (2)].step); - break; } + break; case 86: -#line 696 "test_spec_parse.y" +#line 698 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 87: -#line 697 "test_spec_parse.y" +#line 699 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 88: -#line 698 "test_spec_parse.y" +#line 700 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 89: -#line 699 "test_spec_parse.y" +#line 701 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 90: -#line 700 "test_spec_parse.y" +#line 702 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 91: -#line 701 "test_spec_parse.y" +#line 703 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 92: -#line 702 "test_spec_parse.y" +#line 704 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 93: -#line 703 "test_spec_parse.y" +#line 705 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 94: -#line 704 "test_spec_parse.y" +#line 706 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 95: -#line 705 "test_spec_parse.y" +#line 707 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 96: -#line 706 "test_spec_parse.y" +#line 708 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 97: -#line 707 "test_spec_parse.y" +#line 709 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 98: -#line 708 "test_spec_parse.y" +#line 710 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - break; } + break; case 99: -#line 723 "test_spec_parse.y" +#line 711 "test_spec_parse.y" + { + (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + } + break; + + case 100: +#line 712 "test_spec_parse.y" + { + (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + } + break; + + case 101: +#line 727 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -2828,21 +2866,21 @@ yyparse() sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 100: -#line 730 "test_spec_parse.y" + case 102: +#line 734 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(2) - (2)].str)); - break; } + break; - case 101: -#line 736 "test_spec_parse.y" + case 103: +#line 740 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC_FAILS); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -2851,21 +2889,21 @@ yyparse() sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 102: -#line 743 "test_spec_parse.y" + case 104: +#line 747 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC_FAILS); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(2) - (2)].str)); - break; } + break; - case 103: -#line 749 "test_spec_parse.y" + case 105: +#line 753 "test_spec_parse.y" { /* "pg_autoctl perform failover --formation auth" * EXEC_ARGS returns T_IDENT for first word, T_SHELL_ARGS for rest */ @@ -2874,28 +2912,28 @@ yyparse() (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 104: -#line 757 "test_spec_parse.y" + case 106: +#line 761 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_PG_AUTOCTL); strlcpy((yyval.cmd)->args, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (2)].str)); - break; } + break; - case 105: -#line 763 "test_spec_parse.y" + case 107: +#line 767 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_PG_AUTOCTL); - break; } + break; - case 108: -#line 801 "test_spec_parse.y" + case 110: +#line 805 "test_spec_parse.y" { if (!current_wait_cmd) { @@ -2911,11 +2949,11 @@ yyparse() current_wait_cmd->waitStateCount++; } free((yyvsp[(1) - (4)].str)); - break; } + break; - case 109: -#line 816 "test_spec_parse.y" + case 111: +#line 820 "test_spec_parse.y" { if (!current_wait_cmd) { @@ -2932,11 +2970,11 @@ yyparse() } free((yyvsp[(1) - (4)].str)); free((yyvsp[(4) - (4)].str)); - break; } + break; - case 114: -#line 856 "test_spec_parse.y" + case 116: +#line 860 "test_spec_parse.y" { /* current_pass_cmd set by the enclosing wait_cmd rule */ if (current_pass_cmd && @@ -2948,11 +2986,11 @@ yyparse() (yyvsp[(1) - (1)].str), sizeof(current_pass_cmd->passThroughStates[0])); } - break; } + break; - case 115: -#line 864 "test_spec_parse.y" + case 117: +#line 868 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -2964,11 +3002,11 @@ yyparse() sizeof(current_pass_cmd->passThroughStates[0])); } free((yyvsp[(1) - (1)].str)); - break; } + break; - case 116: -#line 872 "test_spec_parse.y" + case 118: +#line 876 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -2979,11 +3017,11 @@ yyparse() (yyvsp[(3) - (3)].str), sizeof(current_pass_cmd->passThroughStates[0])); } - break; } + break; - case 117: -#line 879 "test_spec_parse.y" + case 119: +#line 883 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -2995,11 +3033,11 @@ yyparse() sizeof(current_pass_cmd->passThroughStates[0])); } free((yyvsp[(3) - (3)].str)); - break; } + break; - case 118: -#line 890 "test_spec_parse.y" + case 120: +#line 894 "test_spec_parse.y" { current_pass_cmd = make_cmd(CMD_WAIT_STATE); strlcpy(current_pass_cmd->service, (yyvsp[(3) - (6)].str), @@ -3007,20 +3045,20 @@ yyparse() strlcpy(current_pass_cmd->state, (yyvsp[(6) - (6)].str), sizeof(current_pass_cmd->state)); free((yyvsp[(3) - (6)].str)); - break; } + break; - case 119: -#line 895 "test_spec_parse.y" + case 121: +#line 899 "test_spec_parse.y" { current_pass_cmd->timeoutSeconds = (yyvsp[(9) - (9)].ival); (yyval.cmd) = current_pass_cmd; current_pass_cmd = NULL; - break; } + break; - case 120: -#line 901 "test_spec_parse.y" + case 122: +#line 905 "test_spec_parse.y" { current_pass_cmd = make_cmd(CMD_WAIT_STATE); strlcpy(current_pass_cmd->service, (yyvsp[(3) - (6)].str), @@ -3029,20 +3067,20 @@ yyparse() sizeof(current_pass_cmd->state)); free((yyvsp[(3) - (6)].str)); free((yyvsp[(6) - (6)].str)); - break; } + break; - case 121: -#line 906 "test_spec_parse.y" + case 123: +#line 910 "test_spec_parse.y" { current_pass_cmd->timeoutSeconds = (yyvsp[(9) - (9)].ival); (yyval.cmd) = current_pass_cmd; current_pass_cmd = NULL; - break; } + break; - case 122: -#line 912 "test_spec_parse.y" + case 124: +#line 916 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STATE); (yyval.cmd)->kind = CMD_ASSERT_ASSIGNED; @@ -3052,11 +3090,11 @@ yyparse() sizeof((yyval.cmd)->state)); (yyval.cmd)->timeoutSeconds = (yyvsp[(7) - (7)].ival); free((yyvsp[(3) - (7)].str)); - break; } + break; - case 123: -#line 921 "test_spec_parse.y" + case 125: +#line 925 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STATE); (yyval.cmd)->kind = CMD_ASSERT_ASSIGNED; @@ -3067,59 +3105,59 @@ yyparse() (yyval.cmd)->timeoutSeconds = (yyvsp[(7) - (7)].ival); free((yyvsp[(3) - (7)].str)); free((yyvsp[(6) - (7)].str)); - break; } + break; - case 124: -#line 930 "test_spec_parse.y" + case 126: +#line 934 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STOPPED); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (5)].str), sizeof((yyval.cmd)->service)); (yyval.cmd)->timeoutSeconds = (yyvsp[(5) - (5)].ival); free((yyvsp[(3) - (5)].str)); - break; } + break; - case 125: -#line 937 "test_spec_parse.y" + case 127: +#line 941 "test_spec_parse.y" { (yyval.cmd) = current_wait_cmd; (yyval.cmd)->timeoutSeconds = (yyvsp[(5) - (5)].ival); current_wait_cmd = NULL; - break; } + break; - case 126: -#line 951 "test_spec_parse.y" + case 128: +#line 955 "test_spec_parse.y" { (yyval.cmd) = current_wait_cmd; (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); current_wait_cmd = NULL; - break; } + break; - case 127: -#line 966 "test_spec_parse.y" + case 129: +#line 970 "test_spec_parse.y" { current_wait_cmd = make_cmd(CMD_WAIT_STATES); strlcpy(current_wait_cmd->waitStates[current_wait_cmd->waitStateCount++], (yyvsp[(1) - (1)].str), sizeof(current_wait_cmd->waitStates[0])); - break; } + break; - case 128: -#line 972 "test_spec_parse.y" + case 130: +#line 976 "test_spec_parse.y" { current_wait_cmd = make_cmd(CMD_WAIT_STATES); strlcpy(current_wait_cmd->waitStates[current_wait_cmd->waitStateCount++], (yyvsp[(1) - (1)].str), sizeof(current_wait_cmd->waitStates[0])); free((yyvsp[(1) - (1)].str)); - break; } + break; - case 129: -#line 979 "test_spec_parse.y" + case 131: +#line 983 "test_spec_parse.y" { if (current_wait_cmd->waitStateCount < PGAF_MAX_WAIT_STATES) { @@ -3128,11 +3166,11 @@ yyparse() (yyvsp[(3) - (3)].str), sizeof(current_wait_cmd->waitStates[0])); } - break; } + break; - case 130: -#line 985 "test_spec_parse.y" + case 132: +#line 989 "test_spec_parse.y" { if (current_wait_cmd->waitStateCount < PGAF_MAX_WAIT_STATES) { @@ -3142,54 +3180,54 @@ yyparse() sizeof(current_wait_cmd->waitStates[0])); } free((yyvsp[(3) - (3)].str)); - break; } + break; - case 133: -#line 1004 "test_spec_parse.y" + case 135: +#line 1008 "test_spec_parse.y" { if (current_wait_cmd->waitGroupCount < PGAF_MAX_WAIT_GROUPS) { current_wait_cmd->waitGroups[current_wait_cmd->waitGroupCount++] = (yyvsp[(2) - (2)].ival); } - break; } + break; - case 134: -#line 1009 "test_spec_parse.y" + case 136: +#line 1013 "test_spec_parse.y" { if (current_wait_cmd->waitGroupCount < PGAF_MAX_WAIT_GROUPS) { current_wait_cmd->waitGroups[current_wait_cmd->waitGroupCount++] = (yyvsp[(4) - (4)].ival); } - break; } + break; - case 135: -#line 1016 "test_spec_parse.y" + case 137: +#line 1020 "test_spec_parse.y" { (yyval.ival) = PGAF_TIMEOUT_DEFAULT; - break; } + break; - case 136: -#line 1017 "test_spec_parse.y" + case 138: +#line 1021 "test_spec_parse.y" { (yyval.ival) = (yyvsp[(2) - (2)].ival); - break; } + break; - case 137: -#line 1018 "test_spec_parse.y" + case 139: +#line 1022 "test_spec_parse.y" { (yyval.ival) = (yyvsp[(3) - (3)].ival); - break; } + break; - case 138: -#line 1030 "test_spec_parse.y" + case 140: +#line 1034 "test_spec_parse.y" { (yyval.cmd) = make_cmd((yyvsp[(6) - (6)].ival) > 0 ? CMD_WAIT_STATE : CMD_ASSERT_STATE); @@ -3199,11 +3237,11 @@ yyparse() sizeof((yyval.cmd)->state)); (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); - break; } + break; - case 139: -#line 1038 "test_spec_parse.y" + case 141: +#line 1042 "test_spec_parse.y" { (yyval.cmd) = make_cmd((yyvsp[(6) - (6)].ival) > 0 ? CMD_WAIT_STATE : CMD_ASSERT_STATE); @@ -3214,11 +3252,11 @@ yyparse() (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); free((yyvsp[(5) - (6)].str)); - break; } + break; - case 140: -#line 1046 "test_spec_parse.y" + case 142: +#line 1050 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_ASSERT_ASSIGNED); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (6)].str), @@ -3227,11 +3265,11 @@ yyparse() sizeof((yyval.cmd)->state)); (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); - break; } + break; - case 141: -#line 1054 "test_spec_parse.y" + case 143: +#line 1058 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_ASSERT_ASSIGNED); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (6)].str), @@ -3241,11 +3279,11 @@ yyparse() (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); free((yyvsp[(5) - (6)].str)); - break; } + break; - case 142: -#line 1072 "test_spec_parse.y" + case 144: +#line 1076 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_SQL); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -3254,58 +3292,57 @@ yyparse() sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 143: -#line 1087 "test_spec_parse.y" + case 145: +#line 1091 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT); strlcpy((yyval.cmd)->expected, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->expected)); expand_tuple_expect((yyval.cmd)->expected, sizeof((yyval.cmd)->expected)); free((yyvsp[(2) - (2)].str)); - break; } + break; - case 144: -#line 1094 "test_spec_parse.y" + case 146: +#line 1098 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); - break; } + break; - case 145: -#line 1098 "test_spec_parse.y" + case 147: +#line 1102 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); strlcpy((yyval.cmd)->state, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->state)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 146: -#line 1104 "test_spec_parse.y" + case 148: +#line 1108 "test_spec_parse.y" { /* SQLSTATE codes like 25006 are all digits, lexed as T_INTEGER */ (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); - snprintf(/* IGNORE-BANNED */ (yyval.cmd)->state, - sizeof((yyval.cmd)->state), "%d", - (yyvsp[(3) - (3)].ival)); - break; + snprintf((yyval.cmd)->state, sizeof((yyval.cmd)->state), "%d", + (yyvsp[(3) - (3)].ival)); } + break; - case 147: -#line 1117 "test_spec_parse.y" + case 149: +#line 1121 "test_spec_parse.y" { (yyval.cmd) = current_promote_cmd; current_promote_cmd = NULL; - break; } + break; - case 148: -#line 1125 "test_spec_parse.y" + case 150: +#line 1129 "test_spec_parse.y" { current_promote_cmd = make_cmd(CMD_PROMOTE); current_promote_cmd->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; @@ -3314,11 +3351,11 @@ yyparse() (yyvsp[(1) - (1)].str), sizeof(current_promote_cmd->promoteNodes[0])); free((yyvsp[(1) - (1)].str)); - break; } + break; - case 149: -#line 1133 "test_spec_parse.y" + case 151: +#line 1137 "test_spec_parse.y" { if (current_promote_cmd->promoteCount < PGAF_MAX_PROMOTE_NODES) { @@ -3329,76 +3366,76 @@ yyparse() sizeof(current_promote_cmd->promoteNodes[0])); } free((yyvsp[(3) - (3)].str)); - break; } + break; - case 150: -#line 1148 "test_spec_parse.y" + case 152: +#line 1152 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_NETWORK_OFF); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 151: -#line 1154 "test_spec_parse.y" + case 153: +#line 1158 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_NETWORK_ON); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 152: -#line 1167 "test_spec_parse.y" + case 154: +#line 1171 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_SLEEP); (yyval.cmd)->timeoutSeconds = (yyvsp[(2) - (2)].ival); - break; } + break; - case 153: -#line 1181 "test_spec_parse.y" + case 155: +#line 1185 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_DOWN); - break; } + break; - case 154: -#line 1185 "test_spec_parse.y" + case 156: +#line 1189 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_START); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 155: -#line 1191 "test_spec_parse.y" + case 157: +#line 1195 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_STOP); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 156: -#line 1197 "test_spec_parse.y" + case 158: +#line 1201 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_KILL); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 157: -#line 1223 "test_spec_parse.y" + case 159: +#line 1227 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_INJECT); strlcpy((yyval.cmd)->expected, (yyvsp[(3) - (4)].str), @@ -3432,45 +3469,45 @@ yyparse() } free((yyvsp[(3) - (4)].str)); free((yyvsp[(4) - (4)].str)); - break; } + break; - case 158: -#line 1257 "test_spec_parse.y" + case 160: +#line 1261 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_STOP_POSTGRES); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 159: -#line 1263 "test_spec_parse.y" + case 161: +#line 1267 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_START_POSTGRES); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 160: -#line 1279 "test_spec_parse.y" + case 162: +#line 1283 "test_spec_parse.y" { pgaf_next_brace_is_while = 1; - break; } + break; - case 161: -#line 1280 "test_spec_parse.y" + case 163: +#line 1284 "test_spec_parse.y" { (yyval.step) = (yyvsp[(4) - (5)].step); - break; } + break; - case 162: -#line 1285 "test_spec_parse.y" + case 164: +#line 1289 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_STAYS_WHILE); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3481,20 +3518,20 @@ yyparse() (5)].step)-> commands : NULL; free((yyvsp[(2) - (5)].str)); - break; } + break; - case 163: -#line 1304 "test_spec_parse.y" + case 165: +#line 1308 "test_spec_parse.y" { /* only "set monitor " is supported; $2 must be "monitor" */ if (strcmp((yyvsp[(2) - (3)].str), "monitor") != 0) { - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: unknown 'set' target '%s' (expected 'monitor')\n", - (yyvsp[(2) - - ( - 3)].str)); + fprintf(stderr, + "pgaftest: unknown 'set' target '%s' (expected 'monitor')\n", + (yyvsp[(2) - + ( + 3)].str)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); YYERROR; @@ -3504,11 +3541,11 @@ yyparse() sizeof((yyval.cmd)->service)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); - break; } + break; - case 164: -#line 1329 "test_spec_parse.y" + case 166: +#line 1333 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (4)].str), @@ -3519,11 +3556,11 @@ yyparse() (yyval.cmd)->allowError = false; /* false = fixed string, true = PCRE */ free((yyvsp[(2) - (4)].str)); free((yyvsp[(4) - (4)].str)); - break; } + break; - case 165: -#line 1338 "test_spec_parse.y" + case 167: +#line 1342 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3534,11 +3571,11 @@ yyparse() (yyval.cmd)->allowError = false; free((yyvsp[(2) - (5)].str)); free((yyvsp[(5) - (5)].str)); - break; } + break; - case 166: -#line 1347 "test_spec_parse.y" + case 168: +#line 1351 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (4)].str), @@ -3549,11 +3586,11 @@ yyparse() (yyval.cmd)->allowError = true; /* true = PCRE (-P) */ free((yyvsp[(2) - (4)].str)); free((yyvsp[(4) - (4)].str)); - break; } + break; - case 167: -#line 1356 "test_spec_parse.y" + case 169: +#line 1360 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3564,11 +3601,50 @@ yyparse() (yyval.cmd)->allowError = true; free((yyvsp[(2) - (5)].str)); free((yyvsp[(5) - (5)].str)); - break; } + break; case 170: -#line 1377 "test_spec_parse.y" +#line 1381 "test_spec_parse.y" + { + (yyval.cmd) = make_cmd(CMD_NODE_ACTIVE); + + /* $2 = "node2 reported: secondary lsn: 0/5A0 ..." */ + strlcpy((yyval.cmd)->args, (yyvsp[(2) - (4)].str), + sizeof((yyval.cmd)->args)); + + /* $4 = "assigned: secondary" */ + strlcpy((yyval.cmd)->nodeActiveExpected, (yyvsp[(4) - (4)].str), + sizeof((yyval.cmd)->nodeActiveExpected)); + free((yyvsp[(2) - (4)].str)); + free((yyvsp[(4) - (4)].str)); + } + break; + + case 171: +#line 1398 "test_spec_parse.y" + { + (yyval.cmd) = make_cmd(CMD_MARK_HEALTH); + strlcpy((yyval.cmd)->service, (yyvsp[(4) - (4)].str), + sizeof((yyval.cmd)->service)); + (yyval.cmd)->markHealthy = true; + free((yyvsp[(4) - (4)].str)); + } + break; + + case 172: +#line 1405 "test_spec_parse.y" + { + (yyval.cmd) = make_cmd(CMD_MARK_HEALTH); + strlcpy((yyval.cmd)->service, (yyvsp[(4) - (4)].str), + sizeof((yyval.cmd)->service)); + (yyval.cmd)->markHealthy = false; + free((yyvsp[(4) - (4)].str)); + } + break; + + case 175: +#line 1424 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -3579,178 +3655,177 @@ yyparse() } else { - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: too many steps in sequence (max %d)\n", - PGAF_MAX_SEQ); + fprintf(stderr, "pgaftest: too many steps in sequence (max %d)\n", + PGAF_MAX_SEQ); exit(1); } - break; } + break; - case 171: -#line 1398 "test_spec_parse.y" + case 176: +#line 1445 "test_spec_parse.y" { (yyval.str) = "init"; - break; } + break; - case 172: -#line 1399 "test_spec_parse.y" + case 177: +#line 1446 "test_spec_parse.y" { (yyval.str) = "single"; - break; } + break; - case 173: -#line 1400 "test_spec_parse.y" + case 178: +#line 1447 "test_spec_parse.y" { (yyval.str) = "primary"; - break; } + break; - case 174: -#line 1401 "test_spec_parse.y" + case 179: +#line 1448 "test_spec_parse.y" { (yyval.str) = "wait_primary"; - break; } + break; - case 175: -#line 1402 "test_spec_parse.y" + case 180: +#line 1449 "test_spec_parse.y" { (yyval.str) = "wait_standby"; - break; } + break; - case 176: -#line 1403 "test_spec_parse.y" + case 181: +#line 1450 "test_spec_parse.y" { (yyval.str) = "demoted"; - break; } + break; - case 177: -#line 1404 "test_spec_parse.y" + case 182: +#line 1451 "test_spec_parse.y" { (yyval.str) = "demote_timeout"; - break; } + break; - case 178: -#line 1405 "test_spec_parse.y" + case 183: +#line 1452 "test_spec_parse.y" { (yyval.str) = "draining"; - break; } + break; - case 179: -#line 1406 "test_spec_parse.y" + case 184: +#line 1453 "test_spec_parse.y" { (yyval.str) = "secondary"; - break; } + break; - case 180: -#line 1407 "test_spec_parse.y" + case 185: +#line 1454 "test_spec_parse.y" { (yyval.str) = "catchingup"; - break; } + break; - case 181: -#line 1408 "test_spec_parse.y" + case 186: +#line 1455 "test_spec_parse.y" { (yyval.str) = "prepare_promotion"; - break; } + break; - case 182: -#line 1409 "test_spec_parse.y" + case 187: +#line 1456 "test_spec_parse.y" { (yyval.str) = "stop_replication"; - break; } + break; - case 183: -#line 1410 "test_spec_parse.y" + case 188: +#line 1457 "test_spec_parse.y" { (yyval.str) = "maintenance"; - break; } + break; - case 184: -#line 1411 "test_spec_parse.y" + case 189: +#line 1458 "test_spec_parse.y" { (yyval.str) = "join_primary"; - break; } + break; - case 185: -#line 1412 "test_spec_parse.y" + case 190: +#line 1459 "test_spec_parse.y" { (yyval.str) = "apply_settings"; - break; } + break; - case 186: -#line 1413 "test_spec_parse.y" + case 191: +#line 1460 "test_spec_parse.y" { (yyval.str) = "prepare_maintenance"; - break; } + break; - case 187: -#line 1414 "test_spec_parse.y" + case 192: +#line 1461 "test_spec_parse.y" { (yyval.str) = "wait_maintenance"; - break; } + break; - case 188: -#line 1415 "test_spec_parse.y" + case 193: +#line 1462 "test_spec_parse.y" { (yyval.str) = "report_lsn"; - break; } + break; - case 189: -#line 1416 "test_spec_parse.y" + case 194: +#line 1463 "test_spec_parse.y" { (yyval.str) = "fast_forward"; - break; } + break; - case 190: -#line 1417 "test_spec_parse.y" + case 195: +#line 1464 "test_spec_parse.y" { (yyval.str) = "join_secondary"; - break; } + break; - case 191: -#line 1418 "test_spec_parse.y" + case 196: +#line 1465 "test_spec_parse.y" { (yyval.str) = "dropped"; - break; } + break; - case 192: -#line 1426 "test_spec_parse.y" + case 197: +#line 1473 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); - break; } + break; - case 193: -#line 1427 "test_spec_parse.y" + case 198: +#line 1474 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); - break; } + break; /* Line 1267 of yacc.c. */ -#line 3360 "test_spec_parse.c" +#line 3430 "test_spec_parse.c" default: { } break; @@ -3784,8 +3859,8 @@ yyparse() /*------------------------------------. - | yyerrlab -- here on detecting error | - | `------------------------------------*/ +| yyerrlab -- here on detecting error | +| `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ @@ -3865,8 +3940,8 @@ yyparse() /*---------------------------------------------------. - | yyerrorlab -- error raised explicitly by YYERROR. | - | `---------------------------------------------------*/ +| yyerrorlab -- error raised explicitly by YYERROR. | +| `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes @@ -3887,8 +3962,8 @@ yyparse() /*-------------------------------------------------------------. - | yyerrlab1 -- common code for both syntax error and YYERROR. | - | `-------------------------------------------------------------*/ +| yyerrlab1 -- common code for both syntax error and YYERROR. | +| `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ @@ -3938,15 +4013,15 @@ yyparse() /*-------------------------------------. - | yyacceptlab -- YYACCEPT comes here. | - | `-------------------------------------*/ +| yyacceptlab -- YYACCEPT comes here. | +| `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. - | yyabortlab -- YYABORT comes here. | - | `-----------------------------------*/ +| yyabortlab -- YYABORT comes here. | +| `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; @@ -3954,8 +4029,8 @@ yyparse() #ifndef yyoverflow /*-------------------------------------------------. - | yyexhaustedlab -- memory exhaustion comes here. | - | `-------------------------------------------------*/ +| yyexhaustedlab -- memory exhaustion comes here. | +| `-------------------------------------------------*/ yyexhaustedlab: yyerror(YY_("memory exhausted")); yyresult = 2; @@ -3998,7 +4073,7 @@ yyparse() } -#line 1430 "test_spec_parse.y" +#line 1477 "test_spec_parse.y" /* ----------------------------------------------------------------------- @@ -4007,23 +4082,22 @@ yyparse() TestSpec * parse_test_spec(const char *filename) { - FILE *f = fopen(filename, "r"); /* IGNORE-BANNED */ + FILE *f = fopen(filename, "r"); if (!f) { - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: cannot open spec file \"%s\": %s\n", - filename, strerror(errno) /* IGNORE-BANNED */); + fprintf(stderr, "pgaftest: cannot open spec file \"%s\": %s\n", + filename, strerror(errno)); return NULL; } TestSpec *spec = (TestSpec *) calloc(1, sizeof(TestSpec)); if (!spec) { - fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ + fprintf(stderr, "out of memory\n"); exit(1); } - strlcpy(spec->filename, filename, sizeof(spec->filename)); + strncpy(spec->filename, filename, sizeof(spec->filename) - 1); current_spec = spec; pgaf_line_number = 1; @@ -4041,7 +4115,7 @@ make_cmd(TestCmdKind kind) TestCmd *c = (TestCmd *) calloc(1, sizeof(TestCmd)); if (!c) { - fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ + fprintf(stderr, "out of memory\n"); exit(1); } c->kind = kind; @@ -4056,12 +4130,12 @@ make_step(const char *name) TestStep *s = (TestStep *) calloc(1, sizeof(TestStep)); if (!s) { - fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ + fprintf(stderr, "out of memory\n"); exit(1); } if (name) { - strlcpy(s->name, name, sizeof(s->name)); + strncpy(s->name, name, sizeof(s->name) - 1); } return s; } diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 9af5fc113..997620cc5 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -187,6 +187,7 @@ static TestNode *current_node = NULL; %token T_LBRACE T_RBRACE T_COMMA %token T_POSTGRES T_STAYS T_WHILE T_THROUGH T_SET %token T_LOGS T_NOT T_CONTAINS T_MATCHES +%token T_NODE_ACTIVE T_MARK T_HEALTHY T_UNHEALTHY /* ---- Tokens with values ---- */ %token T_INTEGER @@ -202,6 +203,7 @@ static TestNode *current_node = NULL; %type exec_cmd wait_cmd assert_cmd sql_cmd expect_cmd %type promote_cmd network_cmd sleep_cmd compose_cmd %type postgres_ctl_cmd stays_while_cmd set_monitor_cmd logs_cmd +%type node_active_cmd mark_health_cmd %type opt_timeout %type while_body @@ -706,6 +708,8 @@ step_cmd: | stays_while_cmd { $$ = $1; } | set_monitor_cmd { $$ = $1; } | logs_cmd { $$ = $1; } + | node_active_cmd { $$ = $1; } + | mark_health_cmd { $$ = $1; } ; /* ----------------------------------------------------------------------- @@ -1363,6 +1367,49 @@ logs_cmd: } ; +/* ----------------------------------------------------------------------- + * node_active { reported: lsn: [tli: N] [pgrunning: bool] } + * expect { assigned: } + * + * The key-value pairs inside the { } braces are read as a raw T_BLOCK string + * and parsed in C by the runner. This keeps the grammar simple and avoids + * introducing a lex state for the block content. + * ----------------------------------------------------------------------- */ + +node_active_cmd: + T_NODE_ACTIVE T_BLOCK T_EXPECT T_BLOCK + { + $$ = make_cmd(CMD_NODE_ACTIVE); + /* $2 = "node2 reported: secondary lsn: 0/5A0 ..." */ + strlcpy($$->args, $2, sizeof($$->args)); + /* $4 = "assigned: secondary" */ + strlcpy($$->nodeActiveExpected, $4, sizeof($$->nodeActiveExpected)); + free($2); free($4); + } + ; + +/* ----------------------------------------------------------------------- + * mark healthy: + * mark unhealthy: + * ----------------------------------------------------------------------- */ + +mark_health_cmd: + T_MARK T_HEALTHY ':' T_IDENT + { + $$ = make_cmd(CMD_MARK_HEALTH); + strlcpy($$->service, $4, sizeof($$->service)); + $$->markHealthy = true; + free($4); + } + | T_MARK T_UNHEALTHY ':' T_IDENT + { + $$ = make_cmd(CMD_MARK_HEALTH); + strlcpy($$->service, $4, sizeof($$->service)); + $$->markHealthy = false; + free($4); + } + ; + /* ----------------------------------------------------------------------- * sequence * ----------------------------------------------------------------------- */ diff --git a/src/bin/pgaftest/test_spec_scan.l b/src/bin/pgaftest/test_spec_scan.l index 0ee5846d2..f2f3beb23 100644 --- a/src/bin/pgaftest/test_spec_scan.l +++ b/src/bin/pgaftest/test_spec_scan.l @@ -293,6 +293,11 @@ static void pgaf_read_raw_block(void); "not" { return T_NOT; } "contains" { return T_CONTAINS; } "matches" { return T_MATCHES; } +"node_active" { return T_NODE_ACTIVE; } +"mark" { return T_MARK; } +"healthy" { return T_HEALTHY; } +"unhealthy" { return T_UNHEALTHY; } +":" { return ':'; } [0-9]+[sS]? { yylval.ival = atoi(yytext); From 7cfd8657b703d330c6aecbb37c371152128b297c Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Fri, 10 Jul 2026 21:19:25 +0200 Subject: [PATCH 03/14] tests: add node_active_protocol.pgaf sample test Demonstrates the new node_active { ... } expect { ... } and mark [un]healthy: syntax against a two-node formation. The test drives a full primary-failure-and-recovery scenario through direct FSM calls to the monitor, without waiting for the keeper heartbeat cycle. Each step asserts the monitor assigns the expected next state given the reported node conditions. --- tests/tap/specs/node_active_protocol.pgaf | 80 +++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tests/tap/specs/node_active_protocol.pgaf diff --git a/tests/tap/specs/node_active_protocol.pgaf b/tests/tap/specs/node_active_protocol.pgaf new file mode 100644 index 000000000..1cb0f0317 --- /dev/null +++ b/tests/tap/specs/node_active_protocol.pgaf @@ -0,0 +1,80 @@ +# Test the monitor's node_active protocol directly. +# +# Uses the `node_active { ... } expect { ... }` DSL to drive the monitor +# FSM through a simple two-node failover scenario without relying on keepers +# running in the background. +# +# Each `node_active` call sends one keeper heartbeat to the monitor and +# asserts the returned assigned state. The `mark [un]healthy` directive +# updates the monitor's health table, simulating what the health-check +# worker does. + +cluster { + monitor + formation { + node1 + node2 + } +} + +setup { + wait until node1 state is single timeout 60s + exec node1 pg_autoctl node start + wait until node1 state is primary + and node2 state is secondary + timeout 90s +} + +teardown { + compose down +} + +# ------------------------------------------------------------------ +# test_001: verify stable primary/secondary state is reflected back +# ------------------------------------------------------------------ +step test_001_steady_state { + # primary reports its current state; monitor should keep assigning primary + node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: primary } + + # secondary reports its current state; monitor should keep assigning secondary + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } +} + +# ------------------------------------------------------------------ +# test_002: simulate primary failure and monitor FSM response +# ------------------------------------------------------------------ +step test_002_primary_failure { + # Mark node1 as unhealthy (simulates health-check worker detecting a failure) + mark unhealthy: node1 + + # node1 stops reporting (pgrunning false); monitor should move to draining + node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: false } + expect { assigned: draining } + + # node2, still healthy, reports secondary; monitor should start promoting it + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: prepare_promotion } +} + +# ------------------------------------------------------------------ +# test_003: restore node1 as secondary after failover completes +# ------------------------------------------------------------------ +step test_003_post_failover { + # node2 completes promotion + node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: primary } + + # Restore node1 health so it can rejoin as secondary + mark healthy: node1 + + # node1 reconnects, reports demoted; monitor assigns catchingup + node_active { node1 reported: demoted lsn: 0/4F00 tli: 1 pgrunning: false } + expect { assigned: catchingup } +} + +sequence + test_001_steady_state + test_002_primary_failure + test_003_post_failover From 73e08530a5a0f4f9d3757bf4b383878d99d1dbc2 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 00:56:39 +0200 Subject: [PATCH 04/14] monitor: fix stale in-memory struct and NodeIsHealthy for scenario mode Three bugs fixed that blocked the pgaftest scenario-mode bootstrap: 1. node_active_protocol.c: sync pgIsRunning, reportedTLI, and reportTime into the in-memory AutoFailoverNode struct after ReportAutoFailoverNodeState. ProceedGroupState->NodeIsHealthy reads pgIsRunning and reportTime from the struct, not from the DB. With the stale values from the previous call the health predicate saw pgIsRunning=false even when the keeper was reporting pgRunning=true, which permanently blocked catchingup->secondary. 2. node_metadata.c NodeIsHealthy: handle NODE_HEALTH_UNKNOWN (-1), the initial health value for newly registered nodes (set by the table DEFAULT). The health-check worker has not run yet for these nodes; trust the keeper's own pgIsRunning report rather than returning false. 3. pgaftest test_runner.c CMD_MARK_HEALTH: run the health UPDATE as the docker OS user (PostgreSQL superuser via peer auth) because autoctl_node lacks write permission on pgautofailover.node. Also corrected the health value: NODE_HEALTH_BAD=0, not -1 (which is UNKNOWN). Also updates the scenario-mode bootstrap in both specs to use pgrunning:true throughout setup. The catchingup->secondary rule requires NodeIsHealthy of the joining node, which in turn needs pgIsRunning=true to have been written to the DB by the previous call. Virtual nodes in setup have no real Postgres process; setting pgrunning:true is the correct semantic (the keeper would report true once replication starts). Tested: node_active_protocol.pgaf (3/3) and monitor_fsm_health.pgaf (4/4) both pass clean. --- src/bin/pgaftest/compose_gen.c | 290 +-- src/bin/pgaftest/test_runner.c | 122 +- src/bin/pgaftest/test_spec.h | 11 + src/bin/pgaftest/test_spec_parse.c | 2064 +++++++++-------- src/bin/pgaftest/test_spec_parse.h | 430 ++-- src/bin/pgaftest/test_spec_parse.y | 99 +- src/bin/pgaftest/test_spec_scan.c | 2519 +++++++++------------ src/bin/pgaftest/test_spec_scan.l | 8 +- src/monitor/node_active_protocol.c | 12 + src/monitor/node_metadata.c | 9 + tests/tap/specs/monitor_fsm_health.pgaf | 198 ++ tests/tap/specs/node_active_protocol.pgaf | 103 +- 12 files changed, 3075 insertions(+), 2790 deletions(-) create mode 100644 tests/tap/specs/monitor_fsm_health.pgaf diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index e993d8963..77234f1ac 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -648,154 +648,155 @@ compose_gen_write(TestCluster *cluster, /* ---- data nodes — iterate all formations ---- */ /* - * Non-default formations are listed in [formation ] sections of the - * monitor.ini. pg_autoctl node run reads them and creates each one after - * the monitor is initialized, before starting the supervisor. - * Data nodes retry registration until their formation exists. + * In scenario (monitor-API-only) mode, nodes are virtual: only names used + * in node_active calls. No data-node containers are generated. */ const TestNode *firstNode = NULL; - for (int fi = 0; fi < cluster->formationCount; fi++) + if (!cluster->monitorApiOnly) { - const TestFormation *form = &cluster->formations[fi]; - - for (int ni = 0; ni < form->nodeCount; ni++) + for (int fi = 0; fi < cluster->formationCount; fi++) { - const TestNode *n = &form->nodes[ni]; - fformat(f, " %s:\n", n->name); - if (n->debianCluster[0]) - { - write_image_stanza_target(f, cluster, contextDir, "debian"); - } - else - { - write_image_stanza(f, cluster, contextDir); - } + const TestFormation *form = &cluster->formations[fi]; - /* debian PGDATA: /var/lib/postgresql// */ - char node_pgdata[MAXPGPATH]; - if (n->debianCluster[0]) + for (int ni = 0; ni < form->nodeCount; ni++) { - sformat(node_pgdata, sizeof(node_pgdata), - DEBIAN_PGDATA_PREFIX "/%s/%s", - debian_pg_version(), n->debianCluster); - } - else - { - strlcpy(node_pgdata, NODE_PGDATA, sizeof(node_pgdata)); - } + const TestNode *n = &form->nodes[ni]; + fformat(f, " %s:\n", n->name); + if (n->debianCluster[0]) + { + write_image_stanza_target(f, cluster, contextDir, "debian"); + } + else + { + write_image_stanza(f, cluster, contextDir); + } + + /* debian PGDATA: /var/lib/postgresql// */ + char node_pgdata[MAXPGPATH]; + if (n->debianCluster[0]) + { + sformat(node_pgdata, sizeof(node_pgdata), + DEBIAN_PGDATA_PREFIX "/%s/%s", + debian_pg_version(), n->debianCluster); + } + else + { + strlcpy(node_pgdata, NODE_PGDATA, sizeof(node_pgdata)); + } - fformat(f, - " hostname: %s\n" - " volumes:\n" - " - %s_data:/var/lib/postgres:rw\n" - " - ./%s.ini:" NODE_INI_PATH ":%s\n", - n->name, - n->name, - n->name, - n->launchDeferred ? "rw" : "ro"); - if (ssl_needs_certs(cluster->ssl)) - { fformat(f, - " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" - " - ./ssl/%s:" - SSL_DIR_IN_CONTAINER "/server:ro\n" - " - ./ssl/client:" - SSL_DIR_IN_CONTAINER "/client:ro\n", - n->name); - } - for (int vi = 0; vi < n->volumeCount; vi++) - { - fformat(f, " - %s_%s:%s:rw\n", - n->volumes[vi].name, n->name, n->volumes[vi].path); - } - if (specDir && specDir[0]) - { + " hostname: %s\n" + " volumes:\n" + " - %s_data:/var/lib/postgres:rw\n" + " - ./%s.ini:" NODE_INI_PATH ":%s\n", + n->name, + n->name, + n->name, + n->launchDeferred ? "rw" : "ro"); + if (ssl_needs_certs(cluster->ssl)) + { + fformat(f, + " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" + " - ./ssl/%s:" + SSL_DIR_IN_CONTAINER "/server:ro\n" + " - ./ssl/client:" + SSL_DIR_IN_CONTAINER "/client:ro\n", + n->name); + } + for (int vi = 0; vi < n->volumeCount; vi++) + { + fformat(f, " - %s_%s:%s:rw\n", + n->volumes[vi].name, n->name, n->volumes[vi].path); + } + if (specDir && specDir[0]) + { + fformat(f, + " - %s:/etc/pgaf/specs:ro\n", specDir); + } fformat(f, - " - %s:/etc/pgaf/specs:ro\n", specDir); - } - fformat(f, - " environment:\n" - " PGDATA: %s\n" - " PGUSER: demo\n" - " PGDATABASE: demo\n" - " PG_AUTOCTL_TEST_DELAY: \"1\"\n" - " expose:\n" - " - 5432\n", - node_pgdata); - - /* - * No depends_on: keeper retry loops handle monitor not yet ready, - * and the formation wait in keeper_register_and_init handles the - * case where the formation hasn't been created yet. - */ + " environment:\n" + " PGDATA: %s\n" + " PGUSER: demo\n" + " PGDATABASE: demo\n" + " PG_AUTOCTL_TEST_DELAY: \"1\"\n" + " expose:\n" + " - 5432\n", + node_pgdata); - /* per-node ssl override may differ from cluster default */ - const char *node_ssl = n->ssl[0] ? n->ssl : cluster->ssl; - fformat(f, - " command: [\"/bin/sh\", \"-c\"," - " \"%s rm -f /tmp/pg_autoctl%s/pg_autoctl.pid" - " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" - " stop_grace_period: 60s\n", - ssl_needs_certs(node_ssl) ? SSL_COPY_CERTS_CMD : "", - node_pgdata); - - /* - * With a monitor: the first data node gets a healthcheck so that - * subsequent nodes use service_healthy depends_on. This ensures - * node1 has registered with the monitor (and become the initial - * primary) before any other node starts, making the initial - * election deterministic. - * - * Without a monitor (no-monitor nodes): the FSM is driven - * manually via pg_autoctl manual fsm assign, so postgres is not - * running when the container starts. No healthcheck; subsequent - * nodes use service_started so they launch as soon as node1 has - * started (they don't need postgres to be ready yet). - */ - if (!firstNode && cluster->withMonitor && !n->launchDeferred) - { /* - * SSL clusters take longer to initialise on slow CI runners - * (cert generation + pg_autoctl SSL config + monitor TLS - * handshake). Double start_period so the runner has time to - * complete init before failures start counting. + * No depends_on: keeper retry loops handle monitor not yet ready, + * and the formation wait in keeper_register_and_init handles the + * case where the formation hasn't been created yet. */ - const char *hc_start = - ssl_needs_certs(node_ssl) ? "300s" : "120s"; - fformat(f, - " healthcheck:\n" - " test: [\"CMD\", \"pg_autoctl\", \"status\"," - " \"--pgdata\", \"%s\"]\n" - " interval: 2s\n" - " timeout: 5s\n" - " retries: 150\n" - " start_period: %s\n", - node_pgdata, hc_start); - } - if (firstNode) - { - fformat(f, - " depends_on:\n" - " %s:\n" - " condition: %s\n", - firstNode->name, - cluster->withMonitor ? "service_healthy" : "service_started"); - } - else if (cluster->withMonitor && !n->launchDeferred) - { - /* node1: wait for monitor to be healthy before starting */ + /* per-node ssl override may differ from cluster default */ + const char *node_ssl = n->ssl[0] ? n->ssl : cluster->ssl; fformat(f, - " depends_on:\n" - " monitor:\n" - " condition: service_healthy\n"); - } - fformat(f, "\n"); + " command: [\"/bin/sh\", \"-c\"," + " \"%s rm -f /tmp/pg_autoctl%s/pg_autoctl.pid" + " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" + " stop_grace_period: 60s\n", + ssl_needs_certs(node_ssl) ? SSL_COPY_CERTS_CMD : "", + node_pgdata); - if (!firstNode && !n->launchDeferred) - { - firstNode = n; + /* + * With a monitor: the first data node gets a healthcheck so that + * subsequent nodes use service_healthy depends_on. This ensures + * node1 has registered with the monitor (and become the initial + * primary) before any other node starts, making the initial + * election deterministic. + * + * Without a monitor (no-monitor nodes): the FSM is driven + * manually via pg_autoctl manual fsm assign, so postgres is not + * running when the container starts. No healthcheck; subsequent + * nodes use service_started so they launch as soon as node1 has + * started (they don't need postgres to be ready yet). + */ + if (!firstNode && cluster->withMonitor && !n->launchDeferred) + { + /* + * SSL clusters take longer to initialise on slow CI runners + * (cert generation + pg_autoctl SSL config + monitor TLS + * handshake). Double start_period so the runner has time to + * complete init before failures start counting. + */ + const char *hc_start = + ssl_needs_certs(node_ssl) ? "300s" : "120s"; + fformat(f, + " healthcheck:\n" + " test: [\"CMD\", \"pg_autoctl\", \"status\"," + " \"--pgdata\", \"%s\"]\n" + " interval: 2s\n" + " timeout: 5s\n" + " retries: 150\n" + " start_period: %s\n", + node_pgdata, hc_start); + } + + if (firstNode) + { + fformat(f, + " depends_on:\n" + " %s:\n" + " condition: %s\n", + firstNode->name, + cluster->withMonitor ? "service_healthy" : "service_started"); + } + else if (cluster->withMonitor && !n->launchDeferred) + { + /* node1: wait for monitor to be healthy before starting */ + fformat(f, + " depends_on:\n" + " monitor:\n" + " condition: service_healthy\n"); + } + fformat(f, "\n"); + + if (!firstNode && !n->launchDeferred) + { + firstNode = n; + } } } } @@ -887,6 +888,14 @@ compose_gen_write(TestCluster *cluster, " condition: service_healthy\n", firstNode->name); } + else if (cluster->monitorApiOnly && cluster->withMonitor) + { + /* scenario mode: no data nodes, wait for monitor only */ + fformat(f, + " depends_on:\n" + " monitor:\n" + " condition: service_healthy\n"); + } fformat(f, " command: [\"pgaftest\", \"run\", \"/spec.pgaf\"]\n\n"); } @@ -900,16 +909,19 @@ compose_gen_write(TestCluster *cluster, { fformat(f, " %s_data:\n", cluster->secondMonitorName); } - for (int fi = 0; fi < cluster->formationCount; fi++) + if (!cluster->monitorApiOnly) { - const TestFormation *form = &cluster->formations[fi]; - for (int ni = 0; ni < form->nodeCount; ni++) + for (int fi = 0; fi < cluster->formationCount; fi++) { - const TestNode *n = &form->nodes[ni]; - fformat(f, " %s_data:\n", n->name); - for (int vi = 0; vi < n->volumeCount; vi++) + const TestFormation *form = &cluster->formations[fi]; + for (int ni = 0; ni < form->nodeCount; ni++) { - fformat(f, " %s_%s:\n", n->volumes[vi].name, n->name); + const TestNode *n = &form->nodes[ni]; + fformat(f, " %s_data:\n", n->name); + for (int vi = 0; vi < n->volumeCount; vi++) + { + fformat(f, " %s_%s:\n", n->volumes[vi].name, n->name); + } } } } diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index 899e513dd..f5b1f300b 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -2378,6 +2378,14 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) case CMD_WAIT_STATE: { + if (r->spec->cluster.monitorApiOnly) + { + sformat(errBuf, errLen, + "wait until is not supported in scenario mode; " + "use node_active calls in setup to drive state"); + return false; + } + /* * LISTEN-driven wait (items 5 & 6). * @@ -2497,6 +2505,41 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) return true; } + case CMD_ASSERT_STATES: + { + /* + * Synchronous multi-node goalstate check. + * Calls monitor_get_node_state() for each (name, expected) pair + * and fails immediately if any mismatch is found. + */ + bool ok = true; + for (int i = 0; i < cmd->waitStateCount; i++) + { + char reported[64] = "", assigned[64] = ""; + if (!monitor_get_node_state(r, cmd->waitNodes[i], + reported, sizeof(reported), + assigned, sizeof(assigned))) + { + sformat(errBuf, errLen, + "assert states: cannot reach monitor " + "to check state of node '%s'", + cmd->waitNodes[i]); + ok = false; + break; + } + if (strcmp(assigned, cmd->waitStates[i]) != 0) + { + sformat(errBuf, errLen, + "assert states: %s assigned-state is \"%s\", " + "expected \"%s\"", + cmd->waitNodes[i], assigned, cmd->waitStates[i]); + ok = false; + break; + } + } + return ok; + } + case CMD_SQL: { strlcpy(r->lastSqlService, cmd->service, sizeof(r->lastSqlService)); @@ -2768,6 +2811,14 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) */ case CMD_WAIT_MULTI: { + if (r->spec->cluster.monitorApiOnly) + { + sformat(errBuf, errLen, + "wait until is not supported in scenario mode; " + "use node_active calls in setup to drive state"); + return false; + } + runner_notify_connect(r); int timeoutSecs = cmd->timeoutSeconds; @@ -3324,6 +3375,49 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) *nl = '\0'; } + /* + * Empty result means the node is not registered yet. In scenario + * mode, virtual nodes are auto-registered on first contact so that + * setup blocks can drive the FSM from scratch using node_active + * calls without needing real pg_autoctl keepers. + */ + if (nodeInfo[0] == '\0' && r->spec->cluster.monitorApiOnly) + { + char regSql[512]; + char regResult[256] = { 0 }; + + /* + * Pass sysidentifier=1 (non-zero) so the check constraint + * "system_identifier_is_null_at_init_only" does not fire + * when reportedstate later advances past 'init'. All + * virtual nodes in the same group get the same value, + * which also satisfies same_system_identifier_within_group. + */ + sformat(regSql, sizeof(regSql), + "SELECT assigned_node_id || '|' || assigned_group_id " + "FROM pgautofailover.register_node(" + "'default', '%s', 5432, 'pg_auto_failover', '%s', 1)", + nodeName, nodeName); + + if (!exec_sql_on_service(r, "monitor", regSql, + regResult, sizeof(regResult))) + { + sformat(errBuf, errLen, + "node_active: auto-register failed for node '%s'", + nodeName); + return false; + } + + char *nl2 = strchr(regResult, '\n'); + if (nl2) + { + *nl2 = '\0'; + } + strlcpy(nodeInfo, regResult, sizeof(nodeInfo)); + log_info(" node_active: registered node '%s' as %s", + nodeName, nodeInfo); + } + long long nodeId = 0; int groupId = 0; if (sscanf(nodeInfo, "%lld|%d", &nodeId, &groupId) != 2) @@ -3382,18 +3476,32 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) * mark healthy/unhealthy: * * Directly update the health column in pgautofailover.node on the - * monitor. health=1 means GOOD, health=-1 means BAD. + * monitor. health=1 (NODE_HEALTH_GOOD), health=0 (NODE_HEALTH_BAD). + * + * Must run as the docker OS user (PostgreSQL superuser via peer + * auth) because autoctl_node lacks write access to this table. */ - int healthValue = cmd->markHealthy ? 1 : -1; + int healthValue = cmd->markHealthy ? 1 : 0; char updateSql[512]; sformat(updateSql, sizeof(updateSql), "UPDATE pgautofailover.node " "SET health = %d, healthchecktime = now() " - "WHERE nodename = '%s'", + "WHERE nodename = \'%s\'", healthValue, cmd->service); + char escapedSql[1024]; + escape_sql_for_shell(updateSql, escapedSql, sizeof(escapedSql)); + char out[256] = { 0 }; - if (!exec_sql_on_service(r, "monitor", updateSql, out, sizeof(out))) + int rc_health = run_cmd_capture(out, sizeof(out), + "%s exec -T -u docker %s " + "psql --tuples-only --no-align " + "-v ON_ERROR_STOP=1 -v VERBOSITY=verbose " + "-d pg_auto_failover -c '%s' 2>&1", + r->composeBase, r->activeMonitorService, + escapedSql); + + if (rc_health != 0) { sformat(errBuf, errLen, "mark %s: UPDATE failed for node '%s': %s", @@ -3613,6 +3721,12 @@ cmd_label(const TestCmd *cmd, char *buf, int len) break; } + case CMD_ASSERT_STATES: + { + sformat(buf, len, "assert states { %d nodes }", cmd->waitStateCount); + break; + } + case CMD_PROMOTE: { char nodes[256] = ""; diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index 0ec208184..4917662aa 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -119,6 +119,14 @@ typedef struct TestCluster char monitorDebianCluster[64]; /* debian-cluster name for the monitor, "" otherwise */ char monitorImageTarget[64]; /* Dockerfile build target for monitor; "" = "run" */ + + /* + * When true the spec was declared with the "scenario { }" keyword rather + * than "cluster { }". Only a monitor service is provisioned; nodes are + * virtual (names only, no containers). node_active and mark_health + * commands are restricted to this mode. + */ + bool monitorApiOnly; } TestCluster; /* ----------------------------------------------------------------------- @@ -177,6 +185,9 @@ typedef enum TestCmdKind */ CMD_NODE_ACTIVE, /* node_active { ... } expect { assigned: ... } */ CMD_MARK_HEALTH, /* mark [un]healthy: */ + + /* assert states { node1: X node2: Y } — sync multi-node goalstate check */ + CMD_ASSERT_STATES, } TestCmdKind; typedef struct TestCmd diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index ee3af898c..910171ff6 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -68,227 +68,231 @@ enum yytokentype { T_CLUSTER = 258, - T_MONITOR = 259, - T_NODE = 260, - T_CITUS_COORDINATOR = 261, - T_CITUS_WORKER = 262, - T_SETUP = 263, - T_TEARDOWN = 264, - T_STEP = 265, - T_SEQUENCE = 266, - T_EQUALS = 267, - T_IMAGE = 268, - T_IMAGE_TARGET = 269, - T_SSL = 270, - T_AUTH = 271, - T_AUTH_METHOD = 272, - T_FORMATION = 273, - T_NUM_SYNC = 274, - T_COORDINATOR = 275, - T_WORKER = 276, - T_ASYNC = 277, - T_NO_MONITOR = 278, - T_LAUNCH = 279, - T_DEFERRED = 280, - T_IMMEDIATE = 281, - T_INITIALLY = 282, - T_VOLUME = 283, - T_LISTEN = 284, - T_CITUS_SECONDARY = 285, - T_CANDIDATE_PRIORITY = 286, - T_PORT = 287, - T_PASSWORD = 288, - T_MONITOR_PASSWORD = 289, - T_CITUS_CLUSTER_NAME = 290, - T_DEBIAN_CLUSTER = 291, - T_REPLICATION_QUORUM = 292, - T_REPLICATION_PASSWORD = 293, - T_EXTENSION_VERSION = 294, - T_BIND_SOURCE = 295, - T_FS_INIT = 296, - T_FS_SINGLE = 297, - T_FS_PRIMARY = 298, - T_FS_WAIT_PRIMARY = 299, - T_FS_WAIT_STANDBY = 300, - T_FS_DEMOTED = 301, - T_FS_DEMOTE_TIMEOUT = 302, - T_FS_DRAINING = 303, - T_FS_SECONDARY = 304, - T_FS_CATCHINGUP = 305, - T_FS_PREP_PROMOTION = 306, - T_FS_STOP_REPLICATION = 307, - T_FS_MAINTENANCE = 308, - T_FS_JOIN_PRIMARY = 309, - T_FS_APPLY_SETTINGS = 310, - T_FS_PREPARE_MAINTENANCE = 311, - T_FS_WAIT_MAINTENANCE = 312, - T_FS_REPORT_LSN = 313, - T_FS_FAST_FORWARD = 314, - T_FS_JOIN_SECONDARY = 315, - T_FS_DROPPED = 316, - T_EXEC = 317, - T_EXEC_FAILS = 318, - T_PG_AUTOCTL = 319, - T_WAIT = 320, - T_UNTIL = 321, - T_TIMEOUT = 322, - T_AND = 323, - T_IS = 324, - T_WITH = 325, - T_ASSERT = 326, - T_SQL = 327, - T_EXPECT = 328, - T_ERROR = 329, - T_PROMOTE = 330, - T_NETWORK = 331, - T_DISCONNECT = 332, - T_CONNECT = 333, - T_SLEEP = 334, - T_COMPOSE = 335, - T_DOWN = 336, - T_START = 337, - T_STOP = 338, - T_STOPPED = 339, - T_KILL = 340, - T_INJECT = 341, - T_STATE = 342, - T_ASSIGNED_STATE = 343, - T_IN = 344, - T_GROUP = 345, - T_LBRACE = 346, - T_RBRACE = 347, - T_COMMA = 348, - T_POSTGRES = 349, - T_STAYS = 350, - T_WHILE = 351, - T_THROUGH = 352, - T_SET = 353, - T_LOGS = 354, - T_NOT = 355, - T_CONTAINS = 356, - T_MATCHES = 357, - T_NODE_ACTIVE = 358, - T_MARK = 359, - T_HEALTHY = 360, - T_UNHEALTHY = 361, - T_INTEGER = 362, - T_IDENT = 363, - T_STRING = 364, - T_BLOCK = 365, - T_SHELL_ARGS = 366 + T_SCENARIO = 259, + T_MONITOR = 260, + T_NODE = 261, + T_CITUS_COORDINATOR = 262, + T_CITUS_WORKER = 263, + T_SETUP = 264, + T_TEARDOWN = 265, + T_STEP = 266, + T_SEQUENCE = 267, + T_EQUALS = 268, + T_IMAGE = 269, + T_IMAGE_TARGET = 270, + T_SSL = 271, + T_AUTH = 272, + T_AUTH_METHOD = 273, + T_FORMATION = 274, + T_NUM_SYNC = 275, + T_COORDINATOR = 276, + T_WORKER = 277, + T_ASYNC = 278, + T_NO_MONITOR = 279, + T_LAUNCH = 280, + T_DEFERRED = 281, + T_IMMEDIATE = 282, + T_INITIALLY = 283, + T_VOLUME = 284, + T_LISTEN = 285, + T_CITUS_SECONDARY = 286, + T_CANDIDATE_PRIORITY = 287, + T_PORT = 288, + T_PASSWORD = 289, + T_MONITOR_PASSWORD = 290, + T_CITUS_CLUSTER_NAME = 291, + T_DEBIAN_CLUSTER = 292, + T_REPLICATION_QUORUM = 293, + T_REPLICATION_PASSWORD = 294, + T_EXTENSION_VERSION = 295, + T_BIND_SOURCE = 296, + T_FS_INIT = 297, + T_FS_SINGLE = 298, + T_FS_PRIMARY = 299, + T_FS_WAIT_PRIMARY = 300, + T_FS_WAIT_STANDBY = 301, + T_FS_DEMOTED = 302, + T_FS_DEMOTE_TIMEOUT = 303, + T_FS_DRAINING = 304, + T_FS_SECONDARY = 305, + T_FS_CATCHINGUP = 306, + T_FS_PREP_PROMOTION = 307, + T_FS_STOP_REPLICATION = 308, + T_FS_MAINTENANCE = 309, + T_FS_JOIN_PRIMARY = 310, + T_FS_APPLY_SETTINGS = 311, + T_FS_PREPARE_MAINTENANCE = 312, + T_FS_WAIT_MAINTENANCE = 313, + T_FS_REPORT_LSN = 314, + T_FS_FAST_FORWARD = 315, + T_FS_JOIN_SECONDARY = 316, + T_FS_DROPPED = 317, + T_EXEC = 318, + T_EXEC_FAILS = 319, + T_PG_AUTOCTL = 320, + T_WAIT = 321, + T_UNTIL = 322, + T_TIMEOUT = 323, + T_AND = 324, + T_IS = 325, + T_WITH = 326, + T_ASSERT = 327, + T_SQL = 328, + T_EXPECT = 329, + T_ERROR = 330, + T_PROMOTE = 331, + T_NETWORK = 332, + T_DISCONNECT = 333, + T_CONNECT = 334, + T_SLEEP = 335, + T_COMPOSE = 336, + T_DOWN = 337, + T_START = 338, + T_STOP = 339, + T_STOPPED = 340, + T_KILL = 341, + T_INJECT = 342, + T_STATE = 343, + T_ASSIGNED_STATE = 344, + T_IN = 345, + T_GROUP = 346, + T_LBRACE = 347, + T_RBRACE = 348, + T_COMMA = 349, + T_POSTGRES = 350, + T_STAYS = 351, + T_WHILE = 352, + T_THROUGH = 353, + T_SET = 354, + T_LOGS = 355, + T_NOT = 356, + T_CONTAINS = 357, + T_MATCHES = 358, + T_NODE_ACTIVE = 359, + T_MARK = 360, + T_HEALTHY = 361, + T_UNHEALTHY = 362, + T_STATES = 363, + T_INTEGER = 364, + T_IDENT = 365, + T_STRING = 366, + T_BLOCK = 367, + T_SHELL_ARGS = 368 }; #endif /* Tokens. */ #define T_CLUSTER 258 -#define T_MONITOR 259 -#define T_NODE 260 -#define T_CITUS_COORDINATOR 261 -#define T_CITUS_WORKER 262 -#define T_SETUP 263 -#define T_TEARDOWN 264 -#define T_STEP 265 -#define T_SEQUENCE 266 -#define T_EQUALS 267 -#define T_IMAGE 268 -#define T_IMAGE_TARGET 269 -#define T_SSL 270 -#define T_AUTH 271 -#define T_AUTH_METHOD 272 -#define T_FORMATION 273 -#define T_NUM_SYNC 274 -#define T_COORDINATOR 275 -#define T_WORKER 276 -#define T_ASYNC 277 -#define T_NO_MONITOR 278 -#define T_LAUNCH 279 -#define T_DEFERRED 280 -#define T_IMMEDIATE 281 -#define T_INITIALLY 282 -#define T_VOLUME 283 -#define T_LISTEN 284 -#define T_CITUS_SECONDARY 285 -#define T_CANDIDATE_PRIORITY 286 -#define T_PORT 287 -#define T_PASSWORD 288 -#define T_MONITOR_PASSWORD 289 -#define T_CITUS_CLUSTER_NAME 290 -#define T_DEBIAN_CLUSTER 291 -#define T_REPLICATION_QUORUM 292 -#define T_REPLICATION_PASSWORD 293 -#define T_EXTENSION_VERSION 294 -#define T_BIND_SOURCE 295 -#define T_FS_INIT 296 -#define T_FS_SINGLE 297 -#define T_FS_PRIMARY 298 -#define T_FS_WAIT_PRIMARY 299 -#define T_FS_WAIT_STANDBY 300 -#define T_FS_DEMOTED 301 -#define T_FS_DEMOTE_TIMEOUT 302 -#define T_FS_DRAINING 303 -#define T_FS_SECONDARY 304 -#define T_FS_CATCHINGUP 305 -#define T_FS_PREP_PROMOTION 306 -#define T_FS_STOP_REPLICATION 307 -#define T_FS_MAINTENANCE 308 -#define T_FS_JOIN_PRIMARY 309 -#define T_FS_APPLY_SETTINGS 310 -#define T_FS_PREPARE_MAINTENANCE 311 -#define T_FS_WAIT_MAINTENANCE 312 -#define T_FS_REPORT_LSN 313 -#define T_FS_FAST_FORWARD 314 -#define T_FS_JOIN_SECONDARY 315 -#define T_FS_DROPPED 316 -#define T_EXEC 317 -#define T_EXEC_FAILS 318 -#define T_PG_AUTOCTL 319 -#define T_WAIT 320 -#define T_UNTIL 321 -#define T_TIMEOUT 322 -#define T_AND 323 -#define T_IS 324 -#define T_WITH 325 -#define T_ASSERT 326 -#define T_SQL 327 -#define T_EXPECT 328 -#define T_ERROR 329 -#define T_PROMOTE 330 -#define T_NETWORK 331 -#define T_DISCONNECT 332 -#define T_CONNECT 333 -#define T_SLEEP 334 -#define T_COMPOSE 335 -#define T_DOWN 336 -#define T_START 337 -#define T_STOP 338 -#define T_STOPPED 339 -#define T_KILL 340 -#define T_INJECT 341 -#define T_STATE 342 -#define T_ASSIGNED_STATE 343 -#define T_IN 344 -#define T_GROUP 345 -#define T_LBRACE 346 -#define T_RBRACE 347 -#define T_COMMA 348 -#define T_POSTGRES 349 -#define T_STAYS 350 -#define T_WHILE 351 -#define T_THROUGH 352 -#define T_SET 353 -#define T_LOGS 354 -#define T_NOT 355 -#define T_CONTAINS 356 -#define T_MATCHES 357 -#define T_NODE_ACTIVE 358 -#define T_MARK 359 -#define T_HEALTHY 360 -#define T_UNHEALTHY 361 -#define T_INTEGER 362 -#define T_IDENT 363 -#define T_STRING 364 -#define T_BLOCK 365 -#define T_SHELL_ARGS 366 +#define T_SCENARIO 259 +#define T_MONITOR 260 +#define T_NODE 261 +#define T_CITUS_COORDINATOR 262 +#define T_CITUS_WORKER 263 +#define T_SETUP 264 +#define T_TEARDOWN 265 +#define T_STEP 266 +#define T_SEQUENCE 267 +#define T_EQUALS 268 +#define T_IMAGE 269 +#define T_IMAGE_TARGET 270 +#define T_SSL 271 +#define T_AUTH 272 +#define T_AUTH_METHOD 273 +#define T_FORMATION 274 +#define T_NUM_SYNC 275 +#define T_COORDINATOR 276 +#define T_WORKER 277 +#define T_ASYNC 278 +#define T_NO_MONITOR 279 +#define T_LAUNCH 280 +#define T_DEFERRED 281 +#define T_IMMEDIATE 282 +#define T_INITIALLY 283 +#define T_VOLUME 284 +#define T_LISTEN 285 +#define T_CITUS_SECONDARY 286 +#define T_CANDIDATE_PRIORITY 287 +#define T_PORT 288 +#define T_PASSWORD 289 +#define T_MONITOR_PASSWORD 290 +#define T_CITUS_CLUSTER_NAME 291 +#define T_DEBIAN_CLUSTER 292 +#define T_REPLICATION_QUORUM 293 +#define T_REPLICATION_PASSWORD 294 +#define T_EXTENSION_VERSION 295 +#define T_BIND_SOURCE 296 +#define T_FS_INIT 297 +#define T_FS_SINGLE 298 +#define T_FS_PRIMARY 299 +#define T_FS_WAIT_PRIMARY 300 +#define T_FS_WAIT_STANDBY 301 +#define T_FS_DEMOTED 302 +#define T_FS_DEMOTE_TIMEOUT 303 +#define T_FS_DRAINING 304 +#define T_FS_SECONDARY 305 +#define T_FS_CATCHINGUP 306 +#define T_FS_PREP_PROMOTION 307 +#define T_FS_STOP_REPLICATION 308 +#define T_FS_MAINTENANCE 309 +#define T_FS_JOIN_PRIMARY 310 +#define T_FS_APPLY_SETTINGS 311 +#define T_FS_PREPARE_MAINTENANCE 312 +#define T_FS_WAIT_MAINTENANCE 313 +#define T_FS_REPORT_LSN 314 +#define T_FS_FAST_FORWARD 315 +#define T_FS_JOIN_SECONDARY 316 +#define T_FS_DROPPED 317 +#define T_EXEC 318 +#define T_EXEC_FAILS 319 +#define T_PG_AUTOCTL 320 +#define T_WAIT 321 +#define T_UNTIL 322 +#define T_TIMEOUT 323 +#define T_AND 324 +#define T_IS 325 +#define T_WITH 326 +#define T_ASSERT 327 +#define T_SQL 328 +#define T_EXPECT 329 +#define T_ERROR 330 +#define T_PROMOTE 331 +#define T_NETWORK 332 +#define T_DISCONNECT 333 +#define T_CONNECT 334 +#define T_SLEEP 335 +#define T_COMPOSE 336 +#define T_DOWN 337 +#define T_START 338 +#define T_STOP 339 +#define T_STOPPED 340 +#define T_KILL 341 +#define T_INJECT 342 +#define T_STATE 343 +#define T_ASSIGNED_STATE 344 +#define T_IN 345 +#define T_GROUP 346 +#define T_LBRACE 347 +#define T_RBRACE 348 +#define T_COMMA 349 +#define T_POSTGRES 350 +#define T_STAYS 351 +#define T_WHILE 352 +#define T_THROUGH 353 +#define T_SET 354 +#define T_LOGS 355 +#define T_NOT 356 +#define T_CONTAINS 357 +#define T_MATCHES 358 +#define T_NODE_ACTIVE 359 +#define T_MARK 360 +#define T_HEALTHY 361 +#define T_UNHEALTHY 362 +#define T_STATES 363 +#define T_INTEGER 364 +#define T_IDENT 365 +#define T_STRING 366 +#define T_BLOCK 367 +#define T_SHELL_ARGS 368 /* Copy the first part of user declarations. */ @@ -523,7 +527,7 @@ typedef union YYSTYPE } /* Line 193 of yacc.c. */ -#line 469 "test_spec_parse.c" +#line 473 "test_spec_parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -535,7 +539,7 @@ YYSTYPE; /* Line 216 of yacc.c. */ -#line 482 "test_spec_parse.c" +#line 486 "test_spec_parse.c" #ifdef short # undef short @@ -751,26 +755,26 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 21 +#define YYFINAL 24 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 581 +#define YYLAST 587 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 113 +#define YYNTOKENS 115 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 64 +#define YYNNTS 68 /* YYNRULES -- Number of rules. */ -#define YYNRULES 198 +#define YYNRULES 208 /* YYNRULES -- Number of states. */ -#define YYNSTATES 325 +#define YYNSTATES 338 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 366 +#define YYMAXUTOK 368 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -783,7 +787,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 112, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 114, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -814,7 +818,7 @@ static const yytype_uint8 yytranslate[] = 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 + 105, 106, 107, 108, 109, 110, 111, 112, 113 }; #if YYDEBUG @@ -824,117 +828,121 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint16 yyprhs[] = { 0, 0, 3, 5, 8, 10, 12, 14, 16, 18, - 19, 25, 26, 29, 31, 33, 35, 37, 39, 41, - 43, 45, 49, 53, 57, 61, 66, 71, 78, 81, - 84, 87, 90, 93, 96, 99, 100, 107, 108, 111, - 113, 115, 117, 119, 121, 123, 126, 127, 130, 132, - 134, 135, 136, 141, 142, 150, 151, 154, 156, 158, - 160, 162, 164, 167, 170, 172, 174, 176, 179, 182, - 185, 188, 191, 194, 197, 200, 203, 206, 209, 213, - 217, 220, 223, 227, 231, 232, 235, 237, 239, 241, - 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, - 263, 265, 269, 272, 276, 279, 283, 286, 288, 290, - 292, 297, 302, 304, 308, 309, 312, 314, 316, 320, - 324, 325, 335, 336, 346, 354, 362, 368, 374, 381, - 383, 385, 389, 393, 394, 397, 400, 405, 406, 409, - 413, 420, 427, 434, 441, 445, 448, 451, 455, 459, - 462, 464, 468, 472, 476, 479, 482, 486, 490, 494, - 499, 503, 507, 508, 514, 520, 524, 529, 535, 540, - 546, 551, 556, 561, 564, 565, 568, 570, 572, 574, - 576, 578, 580, 582, 584, 586, 588, 590, 592, 594, - 596, 598, 600, 602, 604, 606, 608, 610, 612 + 20, 21, 27, 28, 34, 35, 38, 40, 42, 44, + 46, 47, 50, 52, 54, 56, 58, 60, 62, 64, + 66, 70, 74, 78, 82, 87, 92, 99, 102, 105, + 108, 111, 114, 117, 120, 121, 128, 129, 132, 134, + 136, 138, 140, 142, 144, 147, 148, 151, 153, 155, + 156, 157, 162, 163, 171, 172, 175, 177, 179, 181, + 183, 185, 188, 191, 193, 195, 197, 200, 203, 206, + 209, 212, 215, 218, 221, 224, 227, 230, 234, 238, + 241, 244, 248, 252, 253, 256, 258, 260, 262, 264, + 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, + 286, 290, 293, 297, 300, 304, 307, 309, 311, 313, + 318, 323, 325, 329, 330, 333, 335, 337, 341, 345, + 346, 356, 357, 367, 375, 383, 389, 395, 402, 404, + 406, 410, 414, 415, 418, 421, 426, 427, 430, 434, + 441, 448, 455, 462, 466, 470, 473, 476, 480, 484, + 487, 489, 493, 497, 501, 504, 507, 511, 515, 519, + 524, 528, 532, 533, 539, 545, 549, 554, 560, 565, + 571, 576, 581, 586, 589, 590, 593, 595, 597, 599, + 601, 603, 605, 607, 609, 611, 613, 615, 617, 619, + 621, 623, 625, 627, 629, 631, 633, 635, 637 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 114, 0, -1, 115, -1, 114, 115, -1, 116, -1, - 138, -1, 139, -1, 140, -1, 173, -1, -1, 3, - 91, 117, 118, 92, -1, -1, 118, 119, -1, 120, - -1, 121, -1, 123, -1, 124, -1, 122, -1, 125, - -1, 40, -1, 4, -1, 4, 36, 108, -1, 4, - 14, 108, -1, 4, 32, 107, -1, 4, 33, 109, - -1, 4, 108, 24, 25, -1, 4, 108, 27, 84, - -1, 4, 108, 24, 25, 33, 109, -1, 13, 109, - -1, 13, 108, -1, 39, 108, -1, 39, 109, -1, - 15, 108, -1, 16, 108, -1, 17, 108, -1, -1, - 18, 126, 127, 91, 130, 92, -1, -1, 127, 129, - -1, 108, -1, 109, -1, 16, -1, 4, -1, 5, - -1, 128, -1, 19, 107, -1, -1, 130, 133, -1, - 108, -1, 4, -1, -1, -1, 131, 132, 134, 136, - -1, -1, 5, 108, 132, 135, 91, 136, 92, -1, - -1, 136, 137, -1, 20, -1, 21, -1, 22, -1, - 23, -1, 25, -1, 24, 25, -1, 24, 26, -1, - 26, -1, 29, -1, 30, -1, 31, 107, -1, 90, - 107, -1, 32, 107, -1, 35, 108, -1, 36, 108, - -1, 15, 108, -1, 16, 108, -1, 17, 108, -1, - 37, 108, -1, 38, 109, -1, 34, 109, -1, 28, - 108, 108, -1, 28, 108, 109, -1, 8, 141, -1, - 9, 141, -1, 10, 176, 141, -1, 91, 142, 92, - -1, -1, 142, 143, -1, 144, -1, 150, -1, 157, - -1, 158, -1, 159, -1, 160, -1, 162, -1, 163, - -1, 164, -1, 165, -1, 168, -1, 169, -1, 170, - -1, 171, -1, 172, -1, 62, 108, 111, -1, 62, - 108, -1, 63, 108, 111, -1, 63, 108, -1, 64, - 108, 111, -1, 64, 108, -1, 64, -1, 12, -1, - 69, -1, 108, 87, 145, 175, -1, 108, 87, 145, - 108, -1, 146, -1, 147, 68, 146, -1, -1, 97, - 149, -1, 175, -1, 108, -1, 149, 93, 175, -1, - 149, 93, 108, -1, -1, 65, 66, 108, 87, 145, - 175, 151, 148, 156, -1, -1, 65, 66, 108, 87, - 145, 108, 152, 148, 156, -1, 65, 66, 108, 88, - 145, 175, 156, -1, 65, 66, 108, 88, 145, 108, - 156, -1, 65, 66, 108, 84, 156, -1, 65, 66, - 153, 154, 156, -1, 65, 66, 146, 68, 147, 156, - -1, 175, -1, 108, -1, 153, 93, 175, -1, 153, - 93, 108, -1, -1, 89, 155, -1, 90, 107, -1, - 155, 93, 90, 107, -1, -1, 67, 107, -1, 70, - 67, 107, -1, 71, 108, 87, 145, 175, 156, -1, - 71, 108, 87, 145, 108, 156, -1, 71, 108, 88, - 145, 175, 156, -1, 71, 108, 88, 145, 108, 156, - -1, 72, 108, 110, -1, 73, 110, -1, 73, 74, - -1, 73, 74, 108, -1, 73, 74, 107, -1, 75, - 161, -1, 108, -1, 161, 93, 108, -1, 76, 77, - 108, -1, 76, 78, 108, -1, 79, 107, -1, 80, - 81, -1, 80, 82, 108, -1, 80, 83, 108, -1, - 80, 85, 108, -1, 80, 86, 108, 111, -1, 83, - 94, 131, -1, 82, 94, 131, -1, -1, 96, 167, - 91, 142, 92, -1, 71, 131, 95, 175, 166, -1, - 98, 108, 108, -1, 99, 108, 101, 109, -1, 99, - 108, 100, 101, 109, -1, 99, 108, 102, 109, -1, - 99, 108, 100, 102, 109, -1, 103, 110, 73, 110, - -1, 104, 105, 112, 108, -1, 104, 106, 112, 108, - -1, 11, 174, -1, -1, 174, 176, -1, 41, -1, - 42, -1, 43, -1, 44, -1, 45, -1, 46, -1, - 47, -1, 48, -1, 49, -1, 50, -1, 51, -1, - 52, -1, 53, -1, 54, -1, 55, -1, 56, -1, - 57, -1, 58, -1, 59, -1, 60, -1, 61, -1, - 108, -1, 109, -1 + 116, 0, -1, 117, -1, 116, 117, -1, 118, -1, + 120, -1, 144, -1, 145, -1, 146, -1, 179, -1, + -1, 3, 92, 119, 124, 93, -1, -1, 4, 92, + 121, 122, 93, -1, -1, 122, 123, -1, 131, -1, + 127, -1, 129, -1, 130, -1, -1, 124, 125, -1, + 126, -1, 127, -1, 129, -1, 130, -1, 128, -1, + 131, -1, 41, -1, 5, -1, 5, 37, 110, -1, + 5, 15, 110, -1, 5, 33, 109, -1, 5, 34, + 111, -1, 5, 110, 25, 26, -1, 5, 110, 28, + 85, -1, 5, 110, 25, 26, 34, 111, -1, 14, + 111, -1, 14, 110, -1, 40, 110, -1, 40, 111, + -1, 16, 110, -1, 17, 110, -1, 18, 110, -1, + -1, 19, 132, 133, 92, 136, 93, -1, -1, 133, + 135, -1, 110, -1, 111, -1, 17, -1, 5, -1, + 6, -1, 134, -1, 20, 109, -1, -1, 136, 139, + -1, 110, -1, 5, -1, -1, -1, 137, 138, 140, + 142, -1, -1, 6, 110, 138, 141, 92, 142, 93, + -1, -1, 142, 143, -1, 21, -1, 22, -1, 23, + -1, 24, -1, 26, -1, 25, 26, -1, 25, 27, + -1, 27, -1, 30, -1, 31, -1, 32, 109, -1, + 91, 109, -1, 33, 109, -1, 36, 110, -1, 37, + 110, -1, 16, 110, -1, 17, 110, -1, 18, 110, + -1, 38, 110, -1, 39, 111, -1, 35, 111, -1, + 29, 110, 110, -1, 29, 110, 111, -1, 9, 147, + -1, 10, 147, -1, 11, 182, 147, -1, 92, 148, + 93, -1, -1, 148, 149, -1, 150, -1, 156, -1, + 163, -1, 164, -1, 165, -1, 166, -1, 168, -1, + 169, -1, 170, -1, 171, -1, 174, -1, 175, -1, + 176, -1, 177, -1, 178, -1, 63, 110, 113, -1, + 63, 110, -1, 64, 110, 113, -1, 64, 110, -1, + 65, 110, 113, -1, 65, 110, -1, 65, -1, 13, + -1, 70, -1, 110, 88, 151, 181, -1, 110, 88, + 151, 110, -1, 152, -1, 153, 69, 152, -1, -1, + 98, 155, -1, 181, -1, 110, -1, 155, 94, 181, + -1, 155, 94, 110, -1, -1, 66, 67, 110, 88, + 151, 181, 157, 154, 162, -1, -1, 66, 67, 110, + 88, 151, 110, 158, 154, 162, -1, 66, 67, 110, + 89, 151, 181, 162, -1, 66, 67, 110, 89, 151, + 110, 162, -1, 66, 67, 110, 85, 162, -1, 66, + 67, 159, 160, 162, -1, 66, 67, 152, 69, 153, + 162, -1, 181, -1, 110, -1, 159, 94, 181, -1, + 159, 94, 110, -1, -1, 90, 161, -1, 91, 109, + -1, 161, 94, 91, 109, -1, -1, 68, 109, -1, + 71, 68, 109, -1, 72, 110, 88, 151, 181, 162, + -1, 72, 110, 88, 151, 110, 162, -1, 72, 110, + 89, 151, 181, 162, -1, 72, 110, 89, 151, 110, + 162, -1, 72, 108, 112, -1, 73, 110, 112, -1, + 74, 112, -1, 74, 75, -1, 74, 75, 110, -1, + 74, 75, 109, -1, 76, 167, -1, 110, -1, 167, + 94, 110, -1, 77, 78, 110, -1, 77, 79, 110, + -1, 80, 109, -1, 81, 82, -1, 81, 83, 110, + -1, 81, 84, 110, -1, 81, 86, 110, -1, 81, + 87, 110, 113, -1, 84, 95, 137, -1, 83, 95, + 137, -1, -1, 97, 173, 92, 148, 93, -1, 72, + 137, 96, 181, 172, -1, 99, 110, 110, -1, 100, + 110, 102, 111, -1, 100, 110, 101, 102, 111, -1, + 100, 110, 103, 111, -1, 100, 110, 101, 103, 111, + -1, 104, 112, 74, 112, -1, 105, 106, 114, 110, + -1, 105, 107, 114, 110, -1, 12, 180, -1, -1, + 180, 182, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 48, -1, 49, -1, 50, + -1, 51, -1, 52, -1, 53, -1, 54, -1, 55, + -1, 56, -1, 57, -1, 58, -1, 59, -1, 60, + -1, 61, -1, 62, -1, 110, -1, 111, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 213, 213, 214, 218, 219, 220, 221, 222, 235, - 234, 244, 246, 250, 251, 252, 253, 254, 255, 256, - 269, 273, 280, 287, 293, 300, 307, 314, 327, 333, - 343, 349, 359, 369, 375, 386, 385, 402, 404, 413, - 414, 415, 416, 417, 421, 426, 432, 434, 453, 454, - 463, 480, 479, 487, 486, 494, 496, 500, 505, 510, - 514, 518, 522, 526, 530, 534, 538, 542, 546, 550, - 554, 560, 566, 571, 576, 581, 589, 595, 601, 615, - 636, 643, 654, 672, 687, 690, 698, 699, 700, 701, - 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, - 712, 726, 733, 739, 746, 752, 760, 766, 793, 793, - 804, 819, 837, 838, 853, 855, 859, 867, 875, 882, - 894, 893, 905, 904, 915, 924, 933, 940, 954, 969, - 975, 982, 988, 1001, 1003, 1007, 1012, 1020, 1021, 1022, - 1033, 1041, 1049, 1057, 1075, 1090, 1097, 1101, 1107, 1120, - 1128, 1136, 1151, 1157, 1170, 1184, 1188, 1194, 1200, 1226, - 1260, 1266, 1283, 1283, 1288, 1307, 1332, 1341, 1350, 1359, - 1380, 1397, 1404, 1418, 1421, 1423, 1445, 1446, 1447, 1448, - 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, - 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1473, 1474 + 0, 213, 213, 214, 218, 219, 220, 221, 222, 223, + 236, 235, 259, 258, 270, 272, 276, 277, 278, 279, + 282, 284, 288, 289, 290, 291, 292, 293, 294, 307, + 311, 318, 325, 331, 338, 345, 352, 365, 371, 381, + 387, 397, 407, 413, 424, 423, 440, 442, 451, 452, + 453, 454, 455, 459, 464, 470, 472, 491, 492, 501, + 518, 517, 525, 524, 532, 534, 538, 543, 548, 552, + 556, 560, 564, 568, 572, 576, 580, 584, 588, 592, + 598, 604, 609, 614, 619, 627, 633, 639, 653, 674, + 681, 692, 710, 725, 728, 736, 737, 738, 739, 740, + 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, + 764, 771, 777, 784, 790, 798, 804, 831, 831, 842, + 857, 875, 876, 891, 893, 897, 905, 913, 920, 932, + 931, 943, 942, 953, 962, 971, 978, 992, 1007, 1013, + 1020, 1026, 1039, 1041, 1045, 1050, 1058, 1059, 1060, 1071, + 1079, 1087, 1095, 1103, 1155, 1170, 1177, 1181, 1187, 1200, + 1208, 1216, 1231, 1237, 1250, 1264, 1268, 1274, 1280, 1306, + 1340, 1346, 1363, 1363, 1368, 1387, 1412, 1421, 1430, 1439, + 1460, 1482, 1494, 1513, 1516, 1518, 1540, 1541, 1542, 1543, + 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, + 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1568, 1569 }; #endif @@ -944,17 +952,17 @@ static const yytype_uint16 yyrline[] = * First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "T_CLUSTER", "T_MONITOR", "T_NODE", - "T_CITUS_COORDINATOR", "T_CITUS_WORKER", "T_SETUP", "T_TEARDOWN", - "T_STEP", "T_SEQUENCE", "T_EQUALS", "T_IMAGE", "T_IMAGE_TARGET", "T_SSL", - "T_AUTH", "T_AUTH_METHOD", "T_FORMATION", "T_NUM_SYNC", "T_COORDINATOR", - "T_WORKER", "T_ASYNC", "T_NO_MONITOR", "T_LAUNCH", "T_DEFERRED", - "T_IMMEDIATE", "T_INITIALLY", "T_VOLUME", "T_LISTEN", - "T_CITUS_SECONDARY", "T_CANDIDATE_PRIORITY", "T_PORT", "T_PASSWORD", - "T_MONITOR_PASSWORD", "T_CITUS_CLUSTER_NAME", "T_DEBIAN_CLUSTER", - "T_REPLICATION_QUORUM", "T_REPLICATION_PASSWORD", "T_EXTENSION_VERSION", - "T_BIND_SOURCE", "T_FS_INIT", "T_FS_SINGLE", "T_FS_PRIMARY", - "T_FS_WAIT_PRIMARY", "T_FS_WAIT_STANDBY", "T_FS_DEMOTED", + "$end", "error", "$undefined", "T_CLUSTER", "T_SCENARIO", "T_MONITOR", + "T_NODE", "T_CITUS_COORDINATOR", "T_CITUS_WORKER", "T_SETUP", + "T_TEARDOWN", "T_STEP", "T_SEQUENCE", "T_EQUALS", "T_IMAGE", + "T_IMAGE_TARGET", "T_SSL", "T_AUTH", "T_AUTH_METHOD", "T_FORMATION", + "T_NUM_SYNC", "T_COORDINATOR", "T_WORKER", "T_ASYNC", "T_NO_MONITOR", + "T_LAUNCH", "T_DEFERRED", "T_IMMEDIATE", "T_INITIALLY", "T_VOLUME", + "T_LISTEN", "T_CITUS_SECONDARY", "T_CANDIDATE_PRIORITY", "T_PORT", + "T_PASSWORD", "T_MONITOR_PASSWORD", "T_CITUS_CLUSTER_NAME", + "T_DEBIAN_CLUSTER", "T_REPLICATION_QUORUM", "T_REPLICATION_PASSWORD", + "T_EXTENSION_VERSION", "T_BIND_SOURCE", "T_FS_INIT", "T_FS_SINGLE", + "T_FS_PRIMARY", "T_FS_WAIT_PRIMARY", "T_FS_WAIT_STANDBY", "T_FS_DEMOTED", "T_FS_DEMOTE_TIMEOUT", "T_FS_DRAINING", "T_FS_SECONDARY", "T_FS_CATCHINGUP", "T_FS_PREP_PROMOTION", "T_FS_STOP_REPLICATION", "T_FS_MAINTENANCE", "T_FS_JOIN_PRIMARY", "T_FS_APPLY_SETTINGS", @@ -967,22 +975,23 @@ static const char *const yytname[] = "T_INJECT", "T_STATE", "T_ASSIGNED_STATE", "T_IN", "T_GROUP", "T_LBRACE", "T_RBRACE", "T_COMMA", "T_POSTGRES", "T_STAYS", "T_WHILE", "T_THROUGH", "T_SET", "T_LOGS", "T_NOT", "T_CONTAINS", "T_MATCHES", "T_NODE_ACTIVE", - "T_MARK", "T_HEALTHY", "T_UNHEALTHY", "T_INTEGER", "T_IDENT", "T_STRING", - "T_BLOCK", "T_SHELL_ARGS", "':'", "$accept", "spec", "spec_item", - "cluster_block", "@1", "cluster_item_list", "cluster_item", - "monitor_line", "image_line", "extension_version_line", "ssl_line", - "auth_line", "formation_block", "@2", "formation_opt_list", "bare_name", - "formation_opt", "node_list", "node_name", "init_node_slot", "node_line", - "@3", "@4", "node_opt_list", "node_opt", "setup_block", "teardown_block", - "named_step", "cmd_block", "cmd_list", "step_cmd", "exec_cmd", - "state_op", "wait_multi_condition", "wait_multi_condition_list", - "opt_passing_through", "pass_state_list", "wait_cmd", "@5", "@6", - "state_name_list", "opt_in_group", "group_items", "opt_timeout", - "assert_cmd", "sql_cmd", "expect_cmd", "promote_cmd", "promote_list", - "network_cmd", "sleep_cmd", "compose_cmd", "postgres_ctl_cmd", - "while_body", "@7", "stays_while_cmd", "set_monitor_cmd", "logs_cmd", - "node_active_cmd", "mark_health_cmd", "sequence_block", "sequence_names", - "fsm_state", "ident_or_string", 0 + "T_MARK", "T_HEALTHY", "T_UNHEALTHY", "T_STATES", "T_INTEGER", "T_IDENT", + "T_STRING", "T_BLOCK", "T_SHELL_ARGS", "':'", "$accept", "spec", + "spec_item", "cluster_block", "@1", "scenario_block", "@2", + "scenario_item_list", "scenario_item", "cluster_item_list", + "cluster_item", "monitor_line", "image_line", "extension_version_line", + "ssl_line", "auth_line", "formation_block", "@3", "formation_opt_list", + "bare_name", "formation_opt", "node_list", "node_name", "init_node_slot", + "node_line", "@4", "@5", "node_opt_list", "node_opt", "setup_block", + "teardown_block", "named_step", "cmd_block", "cmd_list", "step_cmd", + "exec_cmd", "state_op", "wait_multi_condition", + "wait_multi_condition_list", "opt_passing_through", "pass_state_list", + "wait_cmd", "@6", "@7", "state_name_list", "opt_in_group", "group_items", + "opt_timeout", "assert_cmd", "sql_cmd", "expect_cmd", "promote_cmd", + "promote_list", "network_cmd", "sleep_cmd", "compose_cmd", + "postgres_ctl_cmd", "while_body", "@8", "stays_while_cmd", + "set_monitor_cmd", "logs_cmd", "node_active_cmd", "mark_health_cmd", + "sequence_block", "sequence_names", "fsm_state", "ident_or_string", 0 }; #endif @@ -1003,53 +1012,55 @@ static const yytype_uint16 yytoknum[] = 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 58 + 365, 366, 367, 368, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 113, 114, 114, 115, 115, 115, 115, 115, 117, - 116, 118, 118, 119, 119, 119, 119, 119, 119, 119, - 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, - 122, 122, 123, 124, 124, 126, 125, 127, 127, 128, - 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, - 132, 134, 133, 135, 133, 136, 136, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 138, 139, 140, 141, 142, 142, 143, 143, 143, 143, + 0, 115, 116, 116, 117, 117, 117, 117, 117, 117, + 119, 118, 121, 120, 122, 122, 123, 123, 123, 123, + 124, 124, 125, 125, 125, 125, 125, 125, 125, 126, + 126, 126, 126, 126, 126, 126, 126, 127, 127, 128, + 128, 129, 130, 130, 132, 131, 133, 133, 134, 134, + 134, 134, 134, 135, 135, 136, 136, 137, 137, 138, + 140, 139, 141, 139, 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 144, 144, 144, 144, 144, 144, 144, 145, 145, - 146, 146, 147, 147, 148, 148, 149, 149, 149, 149, - 151, 150, 152, 150, 150, 150, 150, 150, 150, 153, - 153, 153, 153, 154, 154, 155, 155, 156, 156, 156, - 157, 157, 157, 157, 158, 159, 159, 159, 159, 160, - 161, 161, 162, 162, 163, 164, 164, 164, 164, 164, - 165, 165, 167, 166, 168, 169, 170, 170, 170, 170, - 171, 172, 172, 173, 174, 174, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 176, 176 + 143, 143, 143, 143, 143, 143, 143, 143, 143, 144, + 145, 146, 147, 148, 148, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 150, 150, 150, 150, 150, 150, 150, 151, 151, 152, + 152, 153, 153, 154, 154, 155, 155, 155, 155, 157, + 156, 158, 156, 156, 156, 156, 156, 156, 159, 159, + 159, 159, 160, 160, 161, 161, 162, 162, 162, 163, + 163, 163, 163, 163, 164, 165, 165, 165, 165, 166, + 167, 167, 168, 168, 169, 170, 170, 170, 170, 170, + 171, 171, 173, 172, 174, 175, 176, 176, 176, 176, + 177, 178, 178, 179, 180, 180, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 182, 182 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 2, 1, 1, 1, 1, 1, 0, - 5, 0, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 4, 4, 6, 2, 2, - 2, 2, 2, 2, 2, 0, 6, 0, 2, 1, - 1, 1, 1, 1, 1, 2, 0, 2, 1, 1, - 0, 0, 4, 0, 7, 0, 2, 1, 1, 1, - 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, - 2, 2, 3, 3, 0, 2, 1, 1, 1, 1, + 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, + 0, 5, 0, 5, 0, 2, 1, 1, 1, 1, + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 3, 3, 3, 4, 4, 6, 2, 2, 2, + 2, 2, 2, 2, 0, 6, 0, 2, 1, 1, + 1, 1, 1, 1, 2, 0, 2, 1, 1, 0, + 0, 4, 0, 7, 0, 2, 1, 1, 1, 1, + 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, + 2, 3, 3, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 2, 3, 2, 3, 2, 1, 1, 1, - 4, 4, 1, 3, 0, 2, 1, 1, 3, 3, - 0, 9, 0, 9, 7, 7, 5, 5, 6, 1, - 1, 3, 3, 0, 2, 2, 4, 0, 2, 3, - 6, 6, 6, 6, 3, 2, 2, 3, 3, 2, + 3, 2, 3, 2, 3, 2, 1, 1, 1, 4, + 4, 1, 3, 0, 2, 1, 1, 3, 3, 0, + 9, 0, 9, 7, 7, 5, 5, 6, 1, 1, + 3, 3, 0, 2, 2, 4, 0, 2, 3, 6, + 6, 6, 6, 3, 3, 2, 2, 3, 3, 2, 1, 3, 3, 3, 2, 2, 3, 3, 3, 4, 3, 3, 0, 5, 5, 3, 4, 5, 4, 5, 4, 4, 4, 2, 0, 2, 1, 1, 1, 1, @@ -1062,273 +1073,276 @@ static const yytype_uint8 yyr2[] = * means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 0, 174, 0, 2, 4, 5, - 6, 7, 8, 9, 84, 80, 81, 197, 198, 0, - 173, 1, 3, 11, 0, 82, 175, 0, 0, 0, - 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 83, 0, 0, 0, 0, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 20, 0, 0, 0, 0, 35, 0, 19, - 10, 12, 13, 14, 17, 15, 16, 18, 102, 104, - 106, 0, 49, 48, 0, 0, 146, 145, 150, 149, - 0, 0, 154, 155, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 184, 0, 2, 4, + 5, 6, 7, 8, 9, 10, 12, 93, 89, 90, + 207, 208, 0, 183, 1, 3, 20, 14, 0, 91, + 185, 0, 0, 0, 0, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 29, 0, 0, + 0, 0, 44, 0, 28, 11, 21, 22, 23, 26, + 24, 25, 27, 13, 15, 17, 18, 19, 16, 111, + 113, 115, 0, 58, 0, 57, 0, 0, 156, 155, + 160, 159, 0, 0, 164, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 28, 32, 33, 34, 37, 30, 31, 101, 103, - 105, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 130, 0, 133, 129, 0, 0, 0, 144, - 148, 147, 0, 152, 153, 156, 157, 158, 0, 48, - 161, 160, 165, 0, 0, 0, 0, 0, 0, 22, - 23, 24, 21, 0, 0, 0, 137, 0, 0, 0, - 0, 0, 137, 108, 109, 0, 0, 0, 151, 159, - 0, 0, 166, 168, 170, 171, 172, 25, 26, 42, - 43, 41, 0, 46, 39, 40, 44, 38, 0, 0, - 126, 0, 0, 0, 112, 137, 0, 134, 132, 131, - 127, 137, 137, 137, 137, 162, 164, 167, 169, 0, - 45, 0, 138, 0, 122, 120, 137, 137, 0, 0, - 128, 135, 0, 141, 140, 143, 142, 0, 27, 0, - 36, 50, 47, 139, 114, 114, 125, 124, 0, 113, - 0, 84, 50, 51, 0, 137, 137, 111, 110, 136, - 0, 53, 55, 117, 115, 116, 123, 121, 163, 0, - 52, 0, 55, 0, 0, 0, 57, 58, 59, 60, - 0, 61, 64, 0, 65, 66, 0, 0, 0, 0, - 0, 0, 0, 0, 56, 119, 118, 0, 72, 73, - 74, 62, 63, 0, 67, 69, 77, 70, 71, 75, - 76, 68, 54, 78, 79 + 0, 0, 38, 37, 41, 42, 43, 46, 39, 40, + 110, 112, 114, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 139, 0, 142, 138, 153, 0, + 0, 0, 154, 158, 157, 0, 162, 163, 166, 167, + 168, 0, 57, 171, 170, 175, 0, 0, 0, 0, + 0, 0, 31, 32, 33, 30, 0, 0, 0, 146, + 0, 0, 0, 0, 0, 146, 117, 118, 0, 0, + 0, 161, 169, 0, 0, 176, 178, 180, 181, 182, + 34, 35, 51, 52, 50, 0, 55, 48, 49, 53, + 47, 0, 0, 135, 0, 0, 0, 121, 146, 0, + 143, 141, 140, 136, 146, 146, 146, 146, 172, 174, + 177, 179, 0, 54, 0, 147, 0, 131, 129, 146, + 146, 0, 0, 137, 144, 0, 150, 149, 152, 151, + 0, 36, 0, 45, 59, 56, 148, 123, 123, 134, + 133, 0, 122, 0, 93, 59, 60, 0, 146, 146, + 120, 119, 145, 0, 62, 64, 126, 124, 125, 132, + 130, 173, 0, 61, 0, 64, 0, 0, 0, 66, + 67, 68, 69, 0, 70, 73, 0, 74, 75, 0, + 0, 0, 0, 0, 0, 0, 0, 65, 128, 127, + 0, 81, 82, 83, 71, 72, 0, 76, 78, 86, + 79, 80, 84, 85, 77, 63, 87, 88 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 6, 7, 8, 23, 27, 71, 72, 73, 74, - 75, 76, 77, 115, 175, 206, 207, 231, 84, 263, - 252, 272, 279, 280, 304, 9, 10, 11, 15, 24, - 46, 47, 185, 143, 215, 265, 274, 48, 255, 254, - 144, 182, 217, 210, 49, 50, 51, 52, 89, 53, - 54, 55, 56, 226, 247, 57, 58, 59, 60, 61, - 12, 20, 145, 19 + -1, 7, 8, 9, 26, 10, 27, 32, 84, 31, + 76, 77, 78, 79, 80, 81, 82, 127, 188, 219, + 220, 244, 96, 276, 265, 285, 292, 293, 317, 11, + 12, 13, 18, 28, 51, 52, 198, 155, 228, 278, + 287, 53, 268, 267, 156, 195, 230, 223, 54, 55, + 56, 57, 101, 58, 59, 60, 61, 239, 260, 62, + 63, 64, 65, 66, 14, 23, 157, 22 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing * STATE-NUM. */ -#define YYPACT_NINF -171 +#define YYPACT_NINF -180 static const yytype_int16 yypact[] = { - 73, -47, -26, -26, -74, -171, 69, -171, -171, -171, - -171, -171, -171, -171, -171, -171, -171, -171, -171, -26, - -74, -171, -171, -171, 410, -171, -171, 7, -40, -38, - -21, 23, 3, -14, -55, -6, -35, -7, -25, 21, - 27, -171, -2, 19, 15, -31, -171, -171, -171, -171, - -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -5, -17, 20, 34, 40, -171, -11, -171, - -171, -171, -171, -171, -171, -171, -171, -171, 46, 47, - 55, 137, -171, 17, 29, 62, 6, -171, -171, 33, - 91, 92, -171, -171, 93, 95, 96, 98, 4, 4, - 122, -52, 56, 90, 119, 124, 126, 125, 127, 12, - -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -58, 168, -72, -171, 2, 2, 520, -171, - -171, -171, 129, -171, -171, -171, -171, -171, 128, -171, - -171, -171, -171, 16, 131, 132, 133, 130, 134, -171, - -171, -171, -171, 219, 183, -1, -8, 2, 2, 160, - 179, 167, -8, -171, -171, 205, 235, 174, -171, -171, - 162, 163, -171, -171, -171, -171, -171, 240, -171, -171, - -171, -171, 190, -171, -171, -171, -171, -171, 191, 207, - -171, 273, 303, 212, -171, 18, 193, 208, -171, -171, - -171, -8, -8, -8, -8, -171, -171, -171, -171, 194, - -171, 1, -171, 195, 236, 237, -8, -8, 2, 160, - -171, -171, 216, -171, -171, -171, -171, 217, -171, 199, - -171, -171, -171, -171, 213, 213, -171, -171, 341, -171, - 202, -171, -171, -171, 371, -8, -8, -171, -171, -171, - 456, -171, -171, -171, 218, -171, -171, -171, -171, 221, - 139, 409, -171, 227, 228, 229, -171, -171, -171, -171, - 94, -171, -171, 230, -171, -171, 232, 233, 256, 234, - 258, 259, 260, 261, -171, -171, -171, 115, -171, -171, - -171, -171, -171, 14, -171, -171, -171, -171, -171, -171, - -171, -171, -171, -171, -171 + 69, -65, -41, -29, -29, -74, -180, 50, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -29, -74, -180, -180, -180, -180, 414, -180, + -180, 5, 14, -28, -9, 20, 2, 3, 39, -64, + 57, -3, -23, 1, 28, 78, -180, 90, 91, 31, + -1, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -8, 6, 92, + 93, 94, -180, 9, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -180, -180, 118, + 119, 120, 137, -180, 95, 33, -7, 122, 15, -180, + -180, 10, 125, 126, -180, -180, 127, 128, 129, 130, + 4, 4, 131, -6, 41, 132, 155, 133, 96, 134, + 160, 13, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -180, -21, 173, -77, -180, -180, 7, + 7, 525, -180, -180, -180, 161, -180, -180, -180, -180, + -180, 159, -180, -180, -180, -180, 24, 162, 163, 164, + 165, 189, -180, -180, -180, -180, 218, 215, -2, -24, + 7, 7, 191, 211, 167, -24, -180, -180, 206, 236, + 207, -180, -180, 192, 194, -180, -180, -180, -180, -180, + 272, -180, -180, -180, -180, 198, -180, -180, -180, -180, + -180, 199, 241, -180, 275, 305, 222, -180, 23, 202, + 219, -180, -180, -180, -24, -24, -24, -24, -180, -180, + -180, -180, 201, -180, 0, -180, 205, 246, 269, -24, + -24, 7, 191, -180, -180, 248, -180, -180, -180, -180, + 249, -180, 230, -180, -180, -180, -180, 244, 244, -180, + -180, 344, -180, 234, -180, -180, -180, 374, -24, -24, + -180, -180, -180, 461, -180, -180, -180, 250, -180, -180, + -180, -180, 253, 139, 413, -180, 258, 259, 260, -180, + -180, -180, -180, 102, -180, -180, 261, -180, -180, 263, + 264, 265, 267, 268, 270, 271, 266, -180, -180, -180, + 115, -180, -180, -180, -180, -180, 48, -180, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -180 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -171, -171, 335, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -171, -171, -171, -171, -171, -171, -97, 108, - -171, -171, -171, 89, -171, -171, -171, -171, 13, 111, - -171, -171, -137, -166, -171, 118, -171, -171, -171, -171, - -171, -171, -171, -170, -171, -171, -171, -171, -171, -171, - -171, -171, -171, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -148, 354 + -180, -180, 367, -180, -180, -180, -180, -180, -180, -180, + -180, -180, 347, -180, 349, 351, 352, -180, -180, -180, + -180, -180, -110, 135, -180, -180, -180, 112, -180, -180, + -180, -180, 30, 138, -180, -180, -148, -178, -180, 140, + -180, -180, -180, -180, -180, -180, -180, -179, -180, -180, + -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -180, -180, -180, -159, 386 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If * positive, shift that token. If negative, reduce the rule which * number is the opposite. If zero, do what YYDEFACT says. * If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -112 +#define YYTABLE_NINF -121 static const yytype_int16 yytable[] = { - 187, 160, 161, 199, 200, 82, 249, 82, 82, 105, - 186, 62, 220, 214, 183, 201, 16, 180, 202, 86, - 63, 181, 64, 65, 66, 67, 176, 106, 107, 177, - 178, 108, 25, 219, 17, 18, 173, 222, 224, 174, - 211, 212, 90, 91, 13, 240, 68, 69, 163, 164, - 165, 243, 244, 245, 246, 87, 93, 94, 95, 208, - 96, 97, 209, 235, 237, 14, 256, 257, 78, 21, - 79, 184, 1, 259, 103, 104, 1, 2, 3, 4, - 5, 2, 3, 4, 5, 208, 239, 80, 209, 81, - 203, 110, 111, 250, 85, 276, 277, 116, 117, 70, - 92, 258, 88, 109, 146, 147, 100, 204, 205, 159, - 268, 83, 159, 150, 151, 98, 275, 190, 191, 311, - 312, 99, 323, 324, 148, 102, 152, 101, 112, 166, - 283, 284, 285, 306, 251, 286, 287, 288, 289, 290, - 291, 292, 113, 293, 294, 295, 296, 297, 114, 298, - 299, 300, 301, 302, 283, 284, 285, 118, 119, 286, - 287, 288, 289, 290, 291, 292, 120, 293, 294, 295, - 296, 297, 149, 298, 299, 300, 301, 302, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 153, - 154, 155, 167, 156, 157, 303, 158, 322, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 303, - 162, 168, 169, 170, 171, 172, 179, 188, 195, 189, - 192, 193, 196, 194, 197, 142, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 198, 213, 216, - 225, 227, 228, 229, 233, 218, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 230, 232, 238, - 241, 242, 253, 248, -111, -110, 260, 262, 261, 269, - 264, 281, 282, 221, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 308, 309, 310, 313, 314, - 315, 22, 317, 223, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 316, 318, 319, 321, 320, - 271, 307, 270, 266, 26, 0, 0, 0, 0, 0, - 0, 234, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 0, 0, 0, 0, 0, 0, 0, - 0, 236, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 0, 28, 29, 30, 31, 0, 0, 0, 273, - 0, 32, 33, 34, 0, 35, 36, 0, 0, 37, - 38, 0, 39, 40, 0, 0, 0, 0, 0, 0, - 0, 0, 41, 0, 0, 0, 0, 0, 42, 43, - 0, 0, 0, 44, 45, 0, 0, 305, 28, 29, - 30, 31, 0, 0, 0, 0, 0, 32, 33, 34, - 0, 35, 36, 0, 0, 37, 38, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 0, 0, 278, 0, - 0, 0, 0, 0, 42, 43, 0, 0, 0, 44, - 45, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141 + 173, 174, 200, 212, 213, 93, 262, 117, 93, 93, + 67, 98, 199, 193, 227, 214, 233, 194, 215, 68, + 196, 69, 70, 71, 72, 118, 119, 15, 68, 120, + 69, 70, 71, 72, 19, 232, 20, 21, 186, 235, + 237, 187, 224, 225, 221, 73, 74, 222, 99, 253, + 24, 16, 29, 1, 2, 256, 257, 258, 259, 3, + 4, 5, 6, 17, 189, 248, 250, 190, 191, 92, + 269, 270, 1, 2, 272, 102, 103, 197, 3, 4, + 5, 6, 89, 105, 106, 107, 104, 108, 109, 161, + 216, 221, 252, 263, 222, 176, 177, 178, 75, 289, + 290, 90, 121, 271, 165, 115, 116, 83, 217, 218, + 172, 94, 281, 95, 172, 179, 122, 123, 288, 128, + 129, 159, 160, 110, 163, 164, 203, 204, 324, 325, + 91, 296, 297, 298, 264, 319, 299, 300, 301, 302, + 303, 304, 305, 114, 306, 307, 308, 309, 310, 97, + 311, 312, 313, 314, 315, 296, 297, 298, 336, 337, + 299, 300, 301, 302, 303, 304, 305, 100, 306, 307, + 308, 309, 310, 111, 311, 312, 313, 314, 315, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 112, 113, 124, 125, 126, 183, 316, 158, 335, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 316, 130, 131, 132, 162, 166, 167, 168, 169, 170, + 171, 175, 192, 182, 210, 184, 180, 154, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 181, + 185, 201, 202, 205, 206, 208, 207, 231, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 209, + 211, 226, 229, 240, 238, 241, 242, 243, 245, 246, + 251, 254, 261, 255, 266, -120, 234, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, -119, 273, + 275, 274, 277, 282, 294, 295, 236, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 321, 322, + 323, 326, 327, 328, 25, 334, 329, 330, 331, 85, + 332, 86, 333, 87, 88, 247, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 320, 279, 30, + 284, 0, 283, 0, 0, 249, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 280, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 0, 33, 34, 35, + 36, 0, 0, 0, 286, 0, 37, 38, 39, 0, + 40, 41, 0, 0, 42, 43, 0, 44, 45, 0, + 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, + 0, 0, 0, 47, 48, 0, 0, 0, 49, 50, + 0, 0, 0, 318, 33, 34, 35, 36, 0, 0, + 0, 0, 0, 37, 38, 39, 0, 40, 41, 0, + 0, 42, 43, 0, 44, 45, 0, 0, 0, 0, + 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, + 47, 48, 0, 0, 0, 49, 50, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153 }; static const yytype_int16 yycheck[] = { - 148, 98, 99, 4, 5, 4, 5, 4, 4, 14, - 147, 4, 182, 179, 12, 16, 3, 89, 19, 74, - 13, 93, 15, 16, 17, 18, 84, 32, 33, 87, - 88, 36, 19, 181, 108, 109, 24, 185, 186, 27, - 177, 178, 77, 78, 91, 215, 39, 40, 100, 101, - 102, 221, 222, 223, 224, 110, 81, 82, 83, 67, - 85, 86, 70, 211, 212, 91, 236, 237, 108, 0, - 108, 69, 3, 239, 105, 106, 3, 8, 9, 10, - 11, 8, 9, 10, 11, 67, 68, 108, 70, 66, - 91, 108, 109, 92, 108, 265, 266, 108, 109, 92, - 107, 238, 108, 108, 87, 88, 108, 108, 109, 108, - 258, 108, 108, 107, 108, 94, 264, 101, 102, 25, - 26, 94, 108, 109, 95, 110, 93, 108, 108, 73, - 15, 16, 17, 281, 231, 20, 21, 22, 23, 24, - 25, 26, 108, 28, 29, 30, 31, 32, 108, 34, - 35, 36, 37, 38, 15, 16, 17, 111, 111, 20, - 21, 22, 23, 24, 25, 26, 111, 28, 29, 30, - 31, 32, 110, 34, 35, 36, 37, 38, 41, 42, + 110, 111, 161, 5, 6, 5, 6, 15, 5, 5, + 5, 75, 160, 90, 192, 17, 195, 94, 20, 14, + 13, 16, 17, 18, 19, 33, 34, 92, 14, 37, + 16, 17, 18, 19, 4, 194, 110, 111, 25, 198, + 199, 28, 190, 191, 68, 40, 41, 71, 112, 228, + 0, 92, 22, 3, 4, 234, 235, 236, 237, 9, + 10, 11, 12, 92, 85, 224, 225, 88, 89, 67, + 249, 250, 3, 4, 252, 78, 79, 70, 9, 10, + 11, 12, 110, 82, 83, 84, 109, 86, 87, 96, + 92, 68, 69, 93, 71, 101, 102, 103, 93, 278, + 279, 110, 110, 251, 94, 106, 107, 93, 110, 111, + 110, 108, 271, 110, 110, 74, 110, 111, 277, 110, + 111, 88, 89, 95, 109, 110, 102, 103, 26, 27, + 110, 16, 17, 18, 244, 294, 21, 22, 23, 24, + 25, 26, 27, 112, 29, 30, 31, 32, 33, 110, + 35, 36, 37, 38, 39, 16, 17, 18, 110, 111, + 21, 22, 23, 24, 25, 26, 27, 110, 29, 30, + 31, 32, 33, 95, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 108, - 108, 108, 112, 108, 108, 90, 108, 92, 41, 42, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 110, 110, 110, 110, 110, 109, 91, 112, 93, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 90, - 108, 112, 108, 107, 109, 108, 68, 108, 108, 111, - 109, 109, 108, 110, 25, 108, 41, 42, 43, 44, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 91, 113, 113, 113, 112, 110, 110, 110, 110, 110, + 110, 110, 69, 110, 26, 111, 114, 110, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 114, + 110, 110, 113, 111, 111, 110, 112, 110, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 110, + 85, 110, 91, 111, 97, 111, 34, 109, 109, 68, + 88, 109, 111, 94, 109, 69, 110, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 84, 108, 90, - 96, 109, 109, 33, 67, 108, 41, 42, 43, 44, + 55, 56, 57, 58, 59, 60, 61, 62, 69, 91, + 110, 92, 98, 109, 94, 92, 110, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 107, 107, 87, - 107, 93, 107, 109, 68, 68, 90, 108, 91, 107, - 97, 93, 91, 108, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 108, 108, 108, 108, 107, - 107, 6, 108, 108, 41, 42, 43, 44, 45, 46, + 55, 56, 57, 58, 59, 60, 61, 62, 110, 110, + 110, 110, 109, 109, 7, 109, 111, 110, 110, 32, + 110, 32, 111, 32, 32, 110, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 295, 268, 23, + 275, -1, 274, -1, -1, 110, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 110, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 109, 108, 108, 107, 109, - 262, 282, 261, 255, 20, -1, -1, -1, -1, -1, - -1, 108, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, - -1, 108, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, -1, 62, 63, 64, 65, -1, -1, -1, 108, - -1, 71, 72, 73, -1, 75, 76, -1, -1, 79, - 80, -1, 82, 83, -1, -1, -1, -1, -1, -1, - -1, -1, 92, -1, -1, -1, -1, -1, 98, 99, - -1, -1, -1, 103, 104, -1, -1, 108, 62, 63, - 64, 65, -1, -1, -1, -1, -1, 71, 72, 73, - -1, 75, 76, -1, -1, 79, 80, -1, 82, 83, - -1, -1, -1, -1, -1, -1, -1, -1, 92, -1, - -1, -1, -1, -1, 98, 99, -1, -1, -1, 103, - 104, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61 + 57, 58, 59, 60, 61, 62, -1, 63, 64, 65, + 66, -1, -1, -1, 110, -1, 72, 73, 74, -1, + 76, 77, -1, -1, 80, 81, -1, 83, 84, -1, + -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, + -1, -1, -1, 99, 100, -1, -1, -1, 104, 105, + -1, -1, -1, 110, 63, 64, 65, 66, -1, -1, + -1, -1, -1, 72, 73, 74, -1, 76, 77, -1, + -1, 80, 81, -1, 83, 84, -1, -1, -1, -1, + -1, -1, -1, -1, 93, -1, -1, -1, -1, -1, + 99, 100, -1, -1, -1, 104, 105, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing * symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 8, 9, 10, 11, 114, 115, 116, 138, - 139, 140, 173, 91, 91, 141, 141, 108, 109, 176, - 174, 0, 115, 117, 142, 141, 176, 118, 62, 63, - 64, 65, 71, 72, 73, 75, 76, 79, 80, 82, - 83, 92, 98, 99, 103, 104, 143, 144, 150, 157, - 158, 159, 160, 162, 163, 164, 165, 168, 169, 170, - 171, 172, 4, 13, 15, 16, 17, 18, 39, 40, - 92, 119, 120, 121, 122, 123, 124, 125, 108, 108, - 108, 66, 4, 108, 131, 108, 74, 110, 108, 161, - 77, 78, 107, 81, 82, 83, 85, 86, 94, 94, - 108, 108, 110, 105, 106, 14, 32, 33, 36, 108, - 108, 109, 108, 108, 108, 126, 108, 109, 111, 111, - 111, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 108, 146, 153, 175, 87, 88, 95, 110, - 107, 108, 93, 108, 108, 108, 108, 108, 108, 108, - 131, 131, 108, 100, 101, 102, 73, 112, 112, 108, - 107, 109, 108, 24, 27, 127, 84, 87, 88, 68, - 89, 93, 154, 12, 69, 145, 145, 175, 108, 111, - 101, 102, 109, 109, 110, 108, 108, 25, 84, 4, - 5, 16, 19, 91, 108, 109, 128, 129, 67, 70, - 156, 145, 145, 108, 146, 147, 90, 155, 108, 175, - 156, 108, 175, 108, 175, 96, 166, 109, 109, 33, - 107, 130, 107, 67, 108, 175, 108, 175, 87, 68, - 156, 107, 93, 156, 156, 156, 156, 167, 109, 5, - 92, 131, 133, 107, 152, 151, 156, 156, 145, 146, - 90, 91, 108, 132, 97, 148, 148, 108, 175, 107, - 142, 132, 134, 108, 149, 175, 156, 156, 92, 135, - 136, 93, 91, 15, 16, 17, 20, 21, 22, 23, - 24, 25, 26, 28, 29, 30, 31, 32, 34, 35, - 36, 37, 38, 90, 137, 108, 175, 136, 108, 108, - 108, 25, 26, 108, 107, 107, 109, 108, 108, 108, - 109, 107, 92, 108, 109 + 0, 3, 4, 9, 10, 11, 12, 116, 117, 118, + 120, 144, 145, 146, 179, 92, 92, 92, 147, 147, + 110, 111, 182, 180, 0, 117, 119, 121, 148, 147, + 182, 124, 122, 63, 64, 65, 66, 72, 73, 74, + 76, 77, 80, 81, 83, 84, 93, 99, 100, 104, + 105, 149, 150, 156, 163, 164, 165, 166, 168, 169, + 170, 171, 174, 175, 176, 177, 178, 5, 14, 16, + 17, 18, 19, 40, 41, 93, 125, 126, 127, 128, + 129, 130, 131, 93, 123, 127, 129, 130, 131, 110, + 110, 110, 67, 5, 108, 110, 137, 110, 75, 112, + 110, 167, 78, 79, 109, 82, 83, 84, 86, 87, + 95, 95, 110, 110, 112, 106, 107, 15, 33, 34, + 37, 110, 110, 111, 110, 110, 110, 132, 110, 111, + 113, 113, 113, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 110, 152, 159, 181, 112, 88, + 89, 96, 112, 109, 110, 94, 110, 110, 110, 110, + 110, 110, 110, 137, 137, 110, 101, 102, 103, 74, + 114, 114, 110, 109, 111, 110, 25, 28, 133, 85, + 88, 89, 69, 90, 94, 160, 13, 70, 151, 151, + 181, 110, 113, 102, 103, 111, 111, 112, 110, 110, + 26, 85, 5, 6, 17, 20, 92, 110, 111, 134, + 135, 68, 71, 162, 151, 151, 110, 152, 153, 91, + 161, 110, 181, 162, 110, 181, 110, 181, 97, 172, + 111, 111, 34, 109, 136, 109, 68, 110, 181, 110, + 181, 88, 69, 162, 109, 94, 162, 162, 162, 162, + 173, 111, 6, 93, 137, 139, 109, 158, 157, 162, + 162, 151, 152, 91, 92, 110, 138, 98, 154, 154, + 110, 181, 109, 148, 138, 140, 110, 155, 181, 162, + 162, 93, 141, 142, 94, 92, 16, 17, 18, 21, + 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, + 33, 35, 36, 37, 38, 39, 91, 143, 110, 181, + 142, 110, 110, 110, 26, 27, 110, 109, 109, 111, + 110, 110, 110, 111, 109, 93, 110, 111 }; #define yyerrok (yyerrstatus = 0) @@ -1448,8 +1462,8 @@ static const yytype_uint8 yystos[] = /*--------------------------------. -| Print this symbol on YYOUTPUT. | -| `--------------------------------*/ + | Print this symbol on YYOUTPUT. | + | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1486,8 +1500,8 @@ YYSTYPE const *const yyvaluep; /*--------------------------------. -| Print this symbol on YYOUTPUT. | -| `--------------------------------*/ + | Print this symbol on YYOUTPUT. | + | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1513,9 +1527,9 @@ YYSTYPE const *const yyvaluep; } /*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -| `------------------------------------------------------------------*/ + | yy_stack_print -- Print the state stack from its BOTTOM up to its | + | TOP (included). | + | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1542,8 +1556,8 @@ yytype_int16 *top; /*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -| `------------------------------------------------*/ + | Report that the YYRULE is going to be reduced. | + | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -1852,8 +1866,8 @@ yysyntax_error(char *yyresult, int yystate, int yychar) /*-----------------------------------------------. -| Release the memory associated to this symbol. | -| `-----------------------------------------------*/ + | Release the memory associated to this symbol. | + | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1912,8 +1926,8 @@ int yynerrs; /*----------. -| yyparse. | -| `----------*/ + | yyparse. | + | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -2002,8 +2016,8 @@ yyparse() goto yysetstate; /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -| `------------------------------------------------------------*/ + | yynewstate -- Push a new state, which is found in yystate. | + | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks @@ -2094,8 +2108,8 @@ yyparse() goto yybackup; /*-----------. -| yybackup. | -| `-----------*/ + | yybackup. | + | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a @@ -2174,8 +2188,8 @@ yyparse() /*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -| `-----------------------------------------------------------*/ + | yydefault -- do the default action for the current state. | + | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) @@ -2186,8 +2200,8 @@ yyparse() /*-----------------------------. -| yyreduce -- Do a reduction. | -| `-----------------------------*/ + | yyreduce -- Do a reduction. | + | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -2207,8 +2221,8 @@ yyparse() YY_REDUCE_PRINT(yyn); switch (yyn) { - case 9: -#line 235 "test_spec_parse.y" + case 10: +#line 236 "test_spec_parse.y" { strlcpy(current_spec->cluster.ssl, "self-signed", sizeof(current_spec->cluster.ssl)); @@ -2217,22 +2231,34 @@ yyparse() } break; - case 19: -#line 256 "test_spec_parse.y" + case 12: +#line 259 "test_spec_parse.y" + { + current_spec->cluster.monitorApiOnly = true; + current_spec->cluster.withMonitor = true; + strlcpy(current_spec->cluster.ssl, "self-signed", + sizeof(current_spec->cluster.ssl)); + strlcpy(current_spec->cluster.auth, "trust", + sizeof(current_spec->cluster.auth)); + } + break; + + case 28: +#line 294 "test_spec_parse.y" { current_spec->cluster.bindSource = true; } break; - case 20: -#line 270 "test_spec_parse.y" + case 29: +#line 308 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; } break; - case 21: -#line 274 "test_spec_parse.y" + case 30: +#line 312 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorDebianCluster, (yyvsp[(3) - @@ -2242,8 +2268,8 @@ yyparse() } break; - case 22: -#line 281 "test_spec_parse.y" + case 31: +#line 319 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorImageTarget, (yyvsp[(3) - (3)].str), @@ -2252,8 +2278,8 @@ yyparse() } break; - case 23: -#line 288 "test_spec_parse.y" + case 32: +#line 326 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; @@ -2262,8 +2288,8 @@ yyparse() } break; - case 24: -#line 294 "test_spec_parse.y" + case 33: +#line 332 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorPassword, (yyvsp[(3) - (3)].str), @@ -2272,8 +2298,8 @@ yyparse() } break; - case 25: -#line 301 "test_spec_parse.y" + case 34: +#line 339 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (4)].str), sizeof(current_spec->cluster.secondMonitorName)); @@ -2282,8 +2308,8 @@ yyparse() } break; - case 26: -#line 308 "test_spec_parse.y" + case 35: +#line 346 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (4)].str), sizeof(current_spec->cluster.secondMonitorName)); @@ -2292,8 +2318,8 @@ yyparse() } break; - case 27: -#line 315 "test_spec_parse.y" + case 36: +#line 353 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (6)].str), sizeof(current_spec->cluster.secondMonitorName)); @@ -2305,8 +2331,8 @@ yyparse() } break; - case 28: -#line 328 "test_spec_parse.y" + case 37: +#line 366 "test_spec_parse.y" { strlcpy(current_spec->cluster.image, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.image)); @@ -2314,8 +2340,8 @@ yyparse() } break; - case 29: -#line 334 "test_spec_parse.y" + case 38: +#line 372 "test_spec_parse.y" { strlcpy(current_spec->cluster.image, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.image)); @@ -2323,8 +2349,8 @@ yyparse() } break; - case 30: -#line 344 "test_spec_parse.y" + case 39: +#line 382 "test_spec_parse.y" { strlcpy(current_spec->cluster.extensionVersion, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.extensionVersion)); @@ -2332,8 +2358,8 @@ yyparse() } break; - case 31: -#line 350 "test_spec_parse.y" + case 40: +#line 388 "test_spec_parse.y" { strlcpy(current_spec->cluster.extensionVersion, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.extensionVersion)); @@ -2341,8 +2367,8 @@ yyparse() } break; - case 32: -#line 360 "test_spec_parse.y" + case 41: +#line 398 "test_spec_parse.y" { strlcpy(current_spec->cluster.ssl, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.ssl)); @@ -2350,8 +2376,8 @@ yyparse() } break; - case 33: -#line 370 "test_spec_parse.y" + case 42: +#line 408 "test_spec_parse.y" { strlcpy(current_spec->cluster.auth, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.auth)); @@ -2359,8 +2385,8 @@ yyparse() } break; - case 34: -#line 376 "test_spec_parse.y" + case 43: +#line 414 "test_spec_parse.y" { strlcpy(current_spec->cluster.auth, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.auth)); @@ -2368,8 +2394,8 @@ yyparse() } break; - case 35: -#line 386 "test_spec_parse.y" + case 44: +#line 424 "test_spec_parse.y" { TestCluster *cl = ¤t_spec->cluster; if (cl->formationCount >= PGAF_MAX_FORMATIONS) @@ -2385,43 +2411,43 @@ yyparse() } break; - case 39: -#line 413 "test_spec_parse.y" + case 48: +#line 451 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; - case 40: -#line 414 "test_spec_parse.y" + case 49: +#line 452 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; - case 41: -#line 415 "test_spec_parse.y" + case 50: +#line 453 "test_spec_parse.y" { (yyval.str) = strdup("auth"); } break; - case 42: -#line 416 "test_spec_parse.y" + case 51: +#line 454 "test_spec_parse.y" { (yyval.str) = strdup("monitor"); } break; - case 43: -#line 417 "test_spec_parse.y" + case 52: +#line 455 "test_spec_parse.y" { (yyval.str) = strdup("node"); } break; - case 44: -#line 422 "test_spec_parse.y" + case 53: +#line 460 "test_spec_parse.y" { strlcpy(current_formation->name, (yyvsp[(1) - (1)].str), sizeof(current_formation->name)); @@ -2429,29 +2455,29 @@ yyparse() } break; - case 45: -#line 427 "test_spec_parse.y" + case 54: +#line 465 "test_spec_parse.y" { current_formation->numSync = (yyvsp[(2) - (2)].ival); } break; - case 48: -#line 453 "test_spec_parse.y" + case 57: +#line 491 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; - case 49: -#line 454 "test_spec_parse.y" + case 58: +#line 492 "test_spec_parse.y" { (yyval.str) = strdup("monitor"); } break; - case 50: -#line 463 "test_spec_parse.y" + case 59: +#line 501 "test_spec_parse.y" { if (current_formation->nodeCount >= PGAF_MAX_NODES) { @@ -2466,8 +2492,8 @@ yyparse() } break; - case 51: -#line 480 "test_spec_parse.y" + case 60: +#line 518 "test_spec_parse.y" { strlcpy(current_node->name, (yyvsp[(1) - (2)].str), sizeof(current_node->name)); @@ -2475,8 +2501,8 @@ yyparse() } break; - case 53: -#line 487 "test_spec_parse.y" + case 62: +#line 525 "test_spec_parse.y" { strlcpy(current_node->name, (yyvsp[(2) - (3)].str), sizeof(current_node->name)); @@ -2484,101 +2510,101 @@ yyparse() } break; - case 57: -#line 501 "test_spec_parse.y" + case 66: +#line 539 "test_spec_parse.y" { current_node->kind = NODE_KIND_CITUS_COORDINATOR; current_spec->cluster.withCitus = true; } break; - case 58: -#line 506 "test_spec_parse.y" + case 67: +#line 544 "test_spec_parse.y" { current_node->kind = NODE_KIND_CITUS_WORKER; current_spec->cluster.withCitus = true; } break; - case 59: -#line 511 "test_spec_parse.y" + case 68: +#line 549 "test_spec_parse.y" { current_node->replicationQuorum = false; } break; - case 60: -#line 515 "test_spec_parse.y" + case 69: +#line 553 "test_spec_parse.y" { current_node->noMonitor = true; } break; - case 61: -#line 519 "test_spec_parse.y" + case 70: +#line 557 "test_spec_parse.y" { current_node->launchDeferred = true; } break; - case 62: -#line 523 "test_spec_parse.y" + case 71: +#line 561 "test_spec_parse.y" { current_node->launchDeferred = true; } break; - case 63: -#line 527 "test_spec_parse.y" + case 72: +#line 565 "test_spec_parse.y" { current_node->launchDeferred = false; } break; - case 64: -#line 531 "test_spec_parse.y" + case 73: +#line 569 "test_spec_parse.y" { current_node->launchDeferred = false; } break; - case 65: -#line 535 "test_spec_parse.y" + case 74: +#line 573 "test_spec_parse.y" { current_node->listen = true; } break; - case 66: -#line 539 "test_spec_parse.y" + case 75: +#line 577 "test_spec_parse.y" { current_node->citusSecondary = true; } break; - case 67: -#line 543 "test_spec_parse.y" + case 76: +#line 581 "test_spec_parse.y" { current_node->candidatePriority = (yyvsp[(2) - (2)].ival); } break; - case 68: -#line 547 "test_spec_parse.y" + case 77: +#line 585 "test_spec_parse.y" { current_node->group = (yyvsp[(2) - (2)].ival); } break; - case 69: -#line 551 "test_spec_parse.y" + case 78: +#line 589 "test_spec_parse.y" { current_node->pgPort = (yyvsp[(2) - (2)].ival); } break; - case 70: -#line 555 "test_spec_parse.y" + case 79: +#line 593 "test_spec_parse.y" { strlcpy(current_node->citusClusterName, (yyvsp[(2) - (2)].str), sizeof(current_node->citusClusterName)); @@ -2586,8 +2612,8 @@ yyparse() } break; - case 71: -#line 561 "test_spec_parse.y" + case 80: +#line 599 "test_spec_parse.y" { strlcpy(current_node->debianCluster, (yyvsp[(2) - (2)].str), sizeof(current_node->debianCluster)); @@ -2595,8 +2621,8 @@ yyparse() } break; - case 72: -#line 567 "test_spec_parse.y" + case 81: +#line 605 "test_spec_parse.y" { strlcpy(current_node->ssl, (yyvsp[(2) - (2)].str), sizeof(current_node->ssl)); @@ -2604,8 +2630,8 @@ yyparse() } break; - case 73: -#line 572 "test_spec_parse.y" + case 82: +#line 610 "test_spec_parse.y" { strlcpy(current_node->auth, (yyvsp[(2) - (2)].str), sizeof(current_node->auth)); @@ -2613,8 +2639,8 @@ yyparse() } break; - case 74: -#line 577 "test_spec_parse.y" + case 83: +#line 615 "test_spec_parse.y" { strlcpy(current_node->auth, (yyvsp[(2) - (2)].str), sizeof(current_node->auth)); @@ -2622,8 +2648,8 @@ yyparse() } break; - case 75: -#line 582 "test_spec_parse.y" + case 84: +#line 620 "test_spec_parse.y" { if (strcmp((yyvsp[(2) - (2)].str), "false") == 0 || strcmp((yyvsp[(2) - (2)].str), @@ -2639,8 +2665,8 @@ yyparse() } break; - case 76: -#line 590 "test_spec_parse.y" + case 85: +#line 628 "test_spec_parse.y" { strlcpy(current_node->replicationPassword, (yyvsp[(2) - (2)].str), sizeof(current_node->replicationPassword)); @@ -2648,8 +2674,8 @@ yyparse() } break; - case 77: -#line 596 "test_spec_parse.y" + case 86: +#line 634 "test_spec_parse.y" { strlcpy(current_node->monitorPassword, (yyvsp[(2) - (2)].str), sizeof(current_node->monitorPassword)); @@ -2657,8 +2683,8 @@ yyparse() } break; - case 78: -#line 602 "test_spec_parse.y" + case 87: +#line 640 "test_spec_parse.y" { /* volume — adds a named Docker volume */ int vi = current_node->volumeCount; @@ -2675,8 +2701,8 @@ yyparse() } break; - case 79: -#line 616 "test_spec_parse.y" + case 88: +#line 654 "test_spec_parse.y" { /* volume "/path/with spaces" */ int vi = current_node->volumeCount; @@ -2693,22 +2719,22 @@ yyparse() } break; - case 80: -#line 637 "test_spec_parse.y" + case 89: +#line 675 "test_spec_parse.y" { current_spec->setup = (yyvsp[(2) - (2)].step); } break; - case 81: -#line 644 "test_spec_parse.y" + case 90: +#line 682 "test_spec_parse.y" { current_spec->teardown = (yyvsp[(2) - (2)].step); } break; - case 82: -#line 655 "test_spec_parse.y" + case 91: +#line 693 "test_spec_parse.y" { TestStep *s = (yyvsp[(3) - (3)].step); strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); @@ -2717,8 +2743,8 @@ yyparse() } break; - case 83: -#line 673 "test_spec_parse.y" + case 92: +#line 711 "test_spec_parse.y" { /* post-process: CMD_SQL immediately before CMD_EXPECT_ERROR */ for (TestCmd *c = (yyvsp[(2) - (3)].step)->commands; c; c = c->next) @@ -2733,15 +2759,15 @@ yyparse() } break; - case 84: -#line 687 "test_spec_parse.y" + case 93: +#line 725 "test_spec_parse.y" { (yyval.step) = make_step(""); } break; - case 85: -#line 691 "test_spec_parse.y" + case 94: +#line 729 "test_spec_parse.y" { if ((yyvsp[(2) - (2)].cmd)) { @@ -2751,113 +2777,113 @@ yyparse() } break; - case 86: -#line 698 "test_spec_parse.y" + case 95: +#line 736 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 87: -#line 699 "test_spec_parse.y" + case 96: +#line 737 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 88: -#line 700 "test_spec_parse.y" + case 97: +#line 738 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 89: -#line 701 "test_spec_parse.y" + case 98: +#line 739 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 90: -#line 702 "test_spec_parse.y" + case 99: +#line 740 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 91: -#line 703 "test_spec_parse.y" + case 100: +#line 741 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 92: -#line 704 "test_spec_parse.y" + case 101: +#line 742 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 93: -#line 705 "test_spec_parse.y" + case 102: +#line 743 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 94: -#line 706 "test_spec_parse.y" + case 103: +#line 744 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 95: -#line 707 "test_spec_parse.y" + case 104: +#line 745 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 96: -#line 708 "test_spec_parse.y" + case 105: +#line 746 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 97: -#line 709 "test_spec_parse.y" + case 106: +#line 747 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 98: -#line 710 "test_spec_parse.y" + case 107: +#line 748 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 99: -#line 711 "test_spec_parse.y" + case 108: +#line 749 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 100: -#line 712 "test_spec_parse.y" + case 109: +#line 750 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); } break; - case 101: -#line 727 "test_spec_parse.y" + case 110: +#line 765 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -2869,8 +2895,8 @@ yyparse() } break; - case 102: -#line 734 "test_spec_parse.y" + case 111: +#line 772 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (2)].str), @@ -2879,8 +2905,8 @@ yyparse() } break; - case 103: -#line 740 "test_spec_parse.y" + case 112: +#line 778 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC_FAILS); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -2892,8 +2918,8 @@ yyparse() } break; - case 104: -#line 747 "test_spec_parse.y" + case 113: +#line 785 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC_FAILS); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (2)].str), @@ -2902,8 +2928,8 @@ yyparse() } break; - case 105: -#line 753 "test_spec_parse.y" + case 114: +#line 791 "test_spec_parse.y" { /* "pg_autoctl perform failover --formation auth" * EXEC_ARGS returns T_IDENT for first word, T_SHELL_ARGS for rest */ @@ -2915,8 +2941,8 @@ yyparse() } break; - case 106: -#line 761 "test_spec_parse.y" + case 115: +#line 799 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_PG_AUTOCTL); strlcpy((yyval.cmd)->args, (yyvsp[(2) - (2)].str), @@ -2925,15 +2951,15 @@ yyparse() } break; - case 107: -#line 767 "test_spec_parse.y" + case 116: +#line 805 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_PG_AUTOCTL); } break; - case 110: -#line 805 "test_spec_parse.y" + case 119: +#line 843 "test_spec_parse.y" { if (!current_wait_cmd) { @@ -2952,8 +2978,8 @@ yyparse() } break; - case 111: -#line 820 "test_spec_parse.y" + case 120: +#line 858 "test_spec_parse.y" { if (!current_wait_cmd) { @@ -2973,8 +2999,8 @@ yyparse() } break; - case 116: -#line 860 "test_spec_parse.y" + case 125: +#line 898 "test_spec_parse.y" { /* current_pass_cmd set by the enclosing wait_cmd rule */ if (current_pass_cmd && @@ -2989,8 +3015,8 @@ yyparse() } break; - case 117: -#line 868 "test_spec_parse.y" + case 126: +#line 906 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -3005,8 +3031,8 @@ yyparse() } break; - case 118: -#line 876 "test_spec_parse.y" + case 127: +#line 914 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -3020,8 +3046,8 @@ yyparse() } break; - case 119: -#line 883 "test_spec_parse.y" + case 128: +#line 921 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -3036,8 +3062,8 @@ yyparse() } break; - case 120: -#line 894 "test_spec_parse.y" + case 129: +#line 932 "test_spec_parse.y" { current_pass_cmd = make_cmd(CMD_WAIT_STATE); strlcpy(current_pass_cmd->service, (yyvsp[(3) - (6)].str), @@ -3048,8 +3074,8 @@ yyparse() } break; - case 121: -#line 899 "test_spec_parse.y" + case 130: +#line 937 "test_spec_parse.y" { current_pass_cmd->timeoutSeconds = (yyvsp[(9) - (9)].ival); (yyval.cmd) = current_pass_cmd; @@ -3057,8 +3083,8 @@ yyparse() } break; - case 122: -#line 905 "test_spec_parse.y" + case 131: +#line 943 "test_spec_parse.y" { current_pass_cmd = make_cmd(CMD_WAIT_STATE); strlcpy(current_pass_cmd->service, (yyvsp[(3) - (6)].str), @@ -3070,8 +3096,8 @@ yyparse() } break; - case 123: -#line 910 "test_spec_parse.y" + case 132: +#line 948 "test_spec_parse.y" { current_pass_cmd->timeoutSeconds = (yyvsp[(9) - (9)].ival); (yyval.cmd) = current_pass_cmd; @@ -3079,8 +3105,8 @@ yyparse() } break; - case 124: -#line 916 "test_spec_parse.y" + case 133: +#line 954 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STATE); (yyval.cmd)->kind = CMD_ASSERT_ASSIGNED; @@ -3093,8 +3119,8 @@ yyparse() } break; - case 125: -#line 925 "test_spec_parse.y" + case 134: +#line 963 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STATE); (yyval.cmd)->kind = CMD_ASSERT_ASSIGNED; @@ -3108,8 +3134,8 @@ yyparse() } break; - case 126: -#line 934 "test_spec_parse.y" + case 135: +#line 972 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STOPPED); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (5)].str), @@ -3119,8 +3145,8 @@ yyparse() } break; - case 127: -#line 941 "test_spec_parse.y" + case 136: +#line 979 "test_spec_parse.y" { (yyval.cmd) = current_wait_cmd; (yyval.cmd)->timeoutSeconds = (yyvsp[(5) - (5)].ival); @@ -3128,8 +3154,8 @@ yyparse() } break; - case 128: -#line 955 "test_spec_parse.y" + case 137: +#line 993 "test_spec_parse.y" { (yyval.cmd) = current_wait_cmd; (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); @@ -3137,8 +3163,8 @@ yyparse() } break; - case 129: -#line 970 "test_spec_parse.y" + case 138: +#line 1008 "test_spec_parse.y" { current_wait_cmd = make_cmd(CMD_WAIT_STATES); strlcpy(current_wait_cmd->waitStates[current_wait_cmd->waitStateCount++], @@ -3146,8 +3172,8 @@ yyparse() } break; - case 130: -#line 976 "test_spec_parse.y" + case 139: +#line 1014 "test_spec_parse.y" { current_wait_cmd = make_cmd(CMD_WAIT_STATES); strlcpy(current_wait_cmd->waitStates[current_wait_cmd->waitStateCount++], @@ -3156,8 +3182,8 @@ yyparse() } break; - case 131: -#line 983 "test_spec_parse.y" + case 140: +#line 1021 "test_spec_parse.y" { if (current_wait_cmd->waitStateCount < PGAF_MAX_WAIT_STATES) { @@ -3169,8 +3195,8 @@ yyparse() } break; - case 132: -#line 989 "test_spec_parse.y" + case 141: +#line 1027 "test_spec_parse.y" { if (current_wait_cmd->waitStateCount < PGAF_MAX_WAIT_STATES) { @@ -3183,8 +3209,8 @@ yyparse() } break; - case 135: -#line 1008 "test_spec_parse.y" + case 144: +#line 1046 "test_spec_parse.y" { if (current_wait_cmd->waitGroupCount < PGAF_MAX_WAIT_GROUPS) { @@ -3194,8 +3220,8 @@ yyparse() } break; - case 136: -#line 1013 "test_spec_parse.y" + case 145: +#line 1051 "test_spec_parse.y" { if (current_wait_cmd->waitGroupCount < PGAF_MAX_WAIT_GROUPS) { @@ -3205,29 +3231,29 @@ yyparse() } break; - case 137: -#line 1020 "test_spec_parse.y" + case 146: +#line 1058 "test_spec_parse.y" { (yyval.ival) = PGAF_TIMEOUT_DEFAULT; } break; - case 138: -#line 1021 "test_spec_parse.y" + case 147: +#line 1059 "test_spec_parse.y" { (yyval.ival) = (yyvsp[(2) - (2)].ival); } break; - case 139: -#line 1022 "test_spec_parse.y" + case 148: +#line 1060 "test_spec_parse.y" { (yyval.ival) = (yyvsp[(3) - (3)].ival); } break; - case 140: -#line 1034 "test_spec_parse.y" + case 149: +#line 1072 "test_spec_parse.y" { (yyval.cmd) = make_cmd((yyvsp[(6) - (6)].ival) > 0 ? CMD_WAIT_STATE : CMD_ASSERT_STATE); @@ -3240,8 +3266,8 @@ yyparse() } break; - case 141: -#line 1042 "test_spec_parse.y" + case 150: +#line 1080 "test_spec_parse.y" { (yyval.cmd) = make_cmd((yyvsp[(6) - (6)].ival) > 0 ? CMD_WAIT_STATE : CMD_ASSERT_STATE); @@ -3255,8 +3281,8 @@ yyparse() } break; - case 142: -#line 1050 "test_spec_parse.y" + case 151: +#line 1088 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_ASSERT_ASSIGNED); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (6)].str), @@ -3268,8 +3294,8 @@ yyparse() } break; - case 143: -#line 1058 "test_spec_parse.y" + case 152: +#line 1096 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_ASSERT_ASSIGNED); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (6)].str), @@ -3282,8 +3308,79 @@ yyparse() } break; - case 144: -#line 1076 "test_spec_parse.y" + case 153: +#line 1104 "test_spec_parse.y" + { + (yyval.cmd) = make_cmd(CMD_ASSERT_STATES); + + /* T_BLOCK contains "node1: draining node2: prepare_promotion" */ + /* Parse name:state pairs inline */ + char *p = (yyvsp[(3) - (3)].str); + while (*p) + { + while (*p == ' ' || *p == '\t' || *p == '\n') + { + p++; + } + if (*p == '\0') + { + break; + } + + /* name */ + char name[64] = { 0 }; + int ni = 0; + while (*p && *p != ':' && *p != ' ' && *p != '\t') + { + if (ni < 63) + { + name[ni++] = *p; + } + p++; + } + while (*p == ' ' || *p == '\t') + { + p++; + } + if (*p == ':') + { + p++; + } + while (*p == ' ' || *p == '\t') + { + p++; + } + + /* state */ + char state[64] = { 0 }; + int si = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n') + { + if (si < 63) + { + state[si++] = *p; + } + p++; + } + if (name[0] && state[0]) + { + int idx = (yyval.cmd)->waitStateCount; + if (idx < PGAF_MAX_WAIT_STATES) + { + strlcpy((yyval.cmd)->waitNodes[idx], name, + sizeof((yyval.cmd)->waitNodes[0])); + strlcpy((yyval.cmd)->waitStates[idx], state, + sizeof((yyval.cmd)->waitStates[0])); + (yyval.cmd)->waitStateCount++; + } + } + } + free((yyvsp[(3) - (3)].str)); + } + break; + + case 154: +#line 1156 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_SQL); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -3295,8 +3392,8 @@ yyparse() } break; - case 145: -#line 1091 "test_spec_parse.y" + case 155: +#line 1171 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT); strlcpy((yyval.cmd)->expected, (yyvsp[(2) - (2)].str), @@ -3306,15 +3403,15 @@ yyparse() } break; - case 146: -#line 1098 "test_spec_parse.y" + case 156: +#line 1178 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); } break; - case 147: -#line 1102 "test_spec_parse.y" + case 157: +#line 1182 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); strlcpy((yyval.cmd)->state, (yyvsp[(3) - (3)].str), @@ -3323,8 +3420,8 @@ yyparse() } break; - case 148: -#line 1108 "test_spec_parse.y" + case 158: +#line 1188 "test_spec_parse.y" { /* SQLSTATE codes like 25006 are all digits, lexed as T_INTEGER */ (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); @@ -3333,16 +3430,16 @@ yyparse() } break; - case 149: -#line 1121 "test_spec_parse.y" + case 159: +#line 1201 "test_spec_parse.y" { (yyval.cmd) = current_promote_cmd; current_promote_cmd = NULL; } break; - case 150: -#line 1129 "test_spec_parse.y" + case 160: +#line 1209 "test_spec_parse.y" { current_promote_cmd = make_cmd(CMD_PROMOTE); current_promote_cmd->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; @@ -3354,8 +3451,8 @@ yyparse() } break; - case 151: -#line 1137 "test_spec_parse.y" + case 161: +#line 1217 "test_spec_parse.y" { if (current_promote_cmd->promoteCount < PGAF_MAX_PROMOTE_NODES) { @@ -3369,8 +3466,8 @@ yyparse() } break; - case 152: -#line 1152 "test_spec_parse.y" + case 162: +#line 1232 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_NETWORK_OFF); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3379,8 +3476,8 @@ yyparse() } break; - case 153: -#line 1158 "test_spec_parse.y" + case 163: +#line 1238 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_NETWORK_ON); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3389,23 +3486,23 @@ yyparse() } break; - case 154: -#line 1171 "test_spec_parse.y" + case 164: +#line 1251 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_SLEEP); (yyval.cmd)->timeoutSeconds = (yyvsp[(2) - (2)].ival); } break; - case 155: -#line 1185 "test_spec_parse.y" + case 165: +#line 1265 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_DOWN); } break; - case 156: -#line 1189 "test_spec_parse.y" + case 166: +#line 1269 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_START); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3414,8 +3511,8 @@ yyparse() } break; - case 157: -#line 1195 "test_spec_parse.y" + case 167: +#line 1275 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_STOP); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3424,8 +3521,8 @@ yyparse() } break; - case 158: -#line 1201 "test_spec_parse.y" + case 168: +#line 1281 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_KILL); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3434,8 +3531,8 @@ yyparse() } break; - case 159: -#line 1227 "test_spec_parse.y" + case 169: +#line 1307 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_INJECT); strlcpy((yyval.cmd)->expected, (yyvsp[(3) - (4)].str), @@ -3472,8 +3569,8 @@ yyparse() } break; - case 160: -#line 1261 "test_spec_parse.y" + case 170: +#line 1341 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_STOP_POSTGRES); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3482,8 +3579,8 @@ yyparse() } break; - case 161: -#line 1267 "test_spec_parse.y" + case 171: +#line 1347 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_START_POSTGRES); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), @@ -3492,22 +3589,22 @@ yyparse() } break; - case 162: -#line 1283 "test_spec_parse.y" + case 172: +#line 1363 "test_spec_parse.y" { pgaf_next_brace_is_while = 1; } break; - case 163: -#line 1284 "test_spec_parse.y" + case 173: +#line 1364 "test_spec_parse.y" { (yyval.step) = (yyvsp[(4) - (5)].step); } break; - case 164: -#line 1289 "test_spec_parse.y" + case 174: +#line 1369 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_STAYS_WHILE); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3521,8 +3618,8 @@ yyparse() } break; - case 165: -#line 1308 "test_spec_parse.y" + case 175: +#line 1388 "test_spec_parse.y" { /* only "set monitor " is supported; $2 must be "monitor" */ if (strcmp((yyvsp[(2) - (3)].str), "monitor") != 0) @@ -3544,8 +3641,8 @@ yyparse() } break; - case 166: -#line 1333 "test_spec_parse.y" + case 176: +#line 1413 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (4)].str), @@ -3559,8 +3656,8 @@ yyparse() } break; - case 167: -#line 1342 "test_spec_parse.y" + case 177: +#line 1422 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3574,8 +3671,8 @@ yyparse() } break; - case 168: -#line 1351 "test_spec_parse.y" + case 178: +#line 1431 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (4)].str), @@ -3589,8 +3686,8 @@ yyparse() } break; - case 169: -#line 1360 "test_spec_parse.y" + case 179: +#line 1440 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3604,9 +3701,14 @@ yyparse() } break; - case 170: -#line 1381 "test_spec_parse.y" + case 180: +#line 1461 "test_spec_parse.y" { + if (!current_spec->cluster.monitorApiOnly) + { + yyerror("node_active is only allowed inside a scenario { } block; " + "use a cluster { } block for full docker compose tests"); + } (yyval.cmd) = make_cmd(CMD_NODE_ACTIVE); /* $2 = "node2 reported: secondary lsn: 0/5A0 ..." */ @@ -3621,9 +3723,15 @@ yyparse() } break; - case 171: -#line 1398 "test_spec_parse.y" + case 181: +#line 1483 "test_spec_parse.y" { + if (!current_spec->cluster.monitorApiOnly) + { + yyerror( + "mark healthy/unhealthy is only allowed inside a scenario { } " + "block; use a cluster { } block for full docker compose tests"); + } (yyval.cmd) = make_cmd(CMD_MARK_HEALTH); strlcpy((yyval.cmd)->service, (yyvsp[(4) - (4)].str), sizeof((yyval.cmd)->service)); @@ -3632,9 +3740,15 @@ yyparse() } break; - case 172: -#line 1405 "test_spec_parse.y" + case 182: +#line 1495 "test_spec_parse.y" { + if (!current_spec->cluster.monitorApiOnly) + { + yyerror( + "mark healthy/unhealthy is only allowed inside a scenario { } " + "block; use a cluster { } block for full docker compose tests"); + } (yyval.cmd) = make_cmd(CMD_MARK_HEALTH); strlcpy((yyval.cmd)->service, (yyvsp[(4) - (4)].str), sizeof((yyval.cmd)->service)); @@ -3643,8 +3757,8 @@ yyparse() } break; - case 175: -#line 1424 "test_spec_parse.y" + case 185: +#line 1519 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -3662,162 +3776,162 @@ yyparse() } break; - case 176: -#line 1445 "test_spec_parse.y" + case 186: +#line 1540 "test_spec_parse.y" { (yyval.str) = "init"; } break; - case 177: -#line 1446 "test_spec_parse.y" + case 187: +#line 1541 "test_spec_parse.y" { (yyval.str) = "single"; } break; - case 178: -#line 1447 "test_spec_parse.y" + case 188: +#line 1542 "test_spec_parse.y" { (yyval.str) = "primary"; } break; - case 179: -#line 1448 "test_spec_parse.y" + case 189: +#line 1543 "test_spec_parse.y" { (yyval.str) = "wait_primary"; } break; - case 180: -#line 1449 "test_spec_parse.y" + case 190: +#line 1544 "test_spec_parse.y" { (yyval.str) = "wait_standby"; } break; - case 181: -#line 1450 "test_spec_parse.y" + case 191: +#line 1545 "test_spec_parse.y" { (yyval.str) = "demoted"; } break; - case 182: -#line 1451 "test_spec_parse.y" + case 192: +#line 1546 "test_spec_parse.y" { (yyval.str) = "demote_timeout"; } break; - case 183: -#line 1452 "test_spec_parse.y" + case 193: +#line 1547 "test_spec_parse.y" { (yyval.str) = "draining"; } break; - case 184: -#line 1453 "test_spec_parse.y" + case 194: +#line 1548 "test_spec_parse.y" { (yyval.str) = "secondary"; } break; - case 185: -#line 1454 "test_spec_parse.y" + case 195: +#line 1549 "test_spec_parse.y" { (yyval.str) = "catchingup"; } break; - case 186: -#line 1455 "test_spec_parse.y" + case 196: +#line 1550 "test_spec_parse.y" { (yyval.str) = "prepare_promotion"; } break; - case 187: -#line 1456 "test_spec_parse.y" + case 197: +#line 1551 "test_spec_parse.y" { (yyval.str) = "stop_replication"; } break; - case 188: -#line 1457 "test_spec_parse.y" + case 198: +#line 1552 "test_spec_parse.y" { (yyval.str) = "maintenance"; } break; - case 189: -#line 1458 "test_spec_parse.y" + case 199: +#line 1553 "test_spec_parse.y" { (yyval.str) = "join_primary"; } break; - case 190: -#line 1459 "test_spec_parse.y" + case 200: +#line 1554 "test_spec_parse.y" { (yyval.str) = "apply_settings"; } break; - case 191: -#line 1460 "test_spec_parse.y" + case 201: +#line 1555 "test_spec_parse.y" { (yyval.str) = "prepare_maintenance"; } break; - case 192: -#line 1461 "test_spec_parse.y" + case 202: +#line 1556 "test_spec_parse.y" { (yyval.str) = "wait_maintenance"; } break; - case 193: -#line 1462 "test_spec_parse.y" + case 203: +#line 1557 "test_spec_parse.y" { (yyval.str) = "report_lsn"; } break; - case 194: -#line 1463 "test_spec_parse.y" + case 204: +#line 1558 "test_spec_parse.y" { (yyval.str) = "fast_forward"; } break; - case 195: -#line 1464 "test_spec_parse.y" + case 205: +#line 1559 "test_spec_parse.y" { (yyval.str) = "join_secondary"; } break; - case 196: -#line 1465 "test_spec_parse.y" + case 206: +#line 1560 "test_spec_parse.y" { (yyval.str) = "dropped"; } break; - case 197: -#line 1473 "test_spec_parse.y" + case 207: +#line 1568 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } break; - case 198: -#line 1474 "test_spec_parse.y" + case 208: +#line 1569 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); } @@ -3825,7 +3939,7 @@ yyparse() /* Line 1267 of yacc.c. */ -#line 3430 "test_spec_parse.c" +#line 3516 "test_spec_parse.c" default: { } break; @@ -3859,8 +3973,8 @@ yyparse() /*------------------------------------. -| yyerrlab -- here on detecting error | -| `------------------------------------*/ + | yyerrlab -- here on detecting error | + | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ @@ -3940,8 +4054,8 @@ yyparse() /*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -| `---------------------------------------------------*/ + | yyerrorlab -- error raised explicitly by YYERROR. | + | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes @@ -3962,8 +4076,8 @@ yyparse() /*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -| `-------------------------------------------------------------*/ + | yyerrlab1 -- common code for both syntax error and YYERROR. | + | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ @@ -4013,15 +4127,15 @@ yyparse() /*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -| `-------------------------------------*/ + | yyacceptlab -- YYACCEPT comes here. | + | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -| `-----------------------------------*/ + | yyabortlab -- YYABORT comes here. | + | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; @@ -4029,8 +4143,8 @@ yyparse() #ifndef yyoverflow /*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -| `-------------------------------------------------*/ + | yyexhaustedlab -- memory exhaustion comes here. | + | `-------------------------------------------------*/ yyexhaustedlab: yyerror(YY_("memory exhausted")); yyresult = 2; @@ -4073,7 +4187,7 @@ yyparse() } -#line 1477 "test_spec_parse.y" +#line 1572 "test_spec_parse.y" /* ----------------------------------------------------------------------- diff --git a/src/bin/pgaftest/test_spec_parse.h b/src/bin/pgaftest/test_spec_parse.h index 6f62d6019..aabb5eec8 100644 --- a/src/bin/pgaftest/test_spec_parse.h +++ b/src/bin/pgaftest/test_spec_parse.h @@ -42,219 +42,231 @@ enum yytokentype { T_CLUSTER = 258, - T_MONITOR = 259, - T_NODE = 260, - T_CITUS_COORDINATOR = 261, - T_CITUS_WORKER = 262, - T_SETUP = 263, - T_TEARDOWN = 264, - T_STEP = 265, - T_SEQUENCE = 266, - T_EQUALS = 267, - T_IMAGE = 268, - T_IMAGE_TARGET = 269, - T_SSL = 270, - T_AUTH = 271, - T_AUTH_METHOD = 272, - T_FORMATION = 273, - T_NUM_SYNC = 274, - T_COORDINATOR = 275, - T_WORKER = 276, - T_ASYNC = 277, - T_NO_MONITOR = 278, - T_LAUNCH = 279, - T_DEFERRED = 280, - T_IMMEDIATE = 281, - T_INITIALLY = 282, - T_VOLUME = 283, - T_LISTEN = 284, - T_CITUS_SECONDARY = 285, - T_CANDIDATE_PRIORITY = 286, - T_PORT = 287, - T_PASSWORD = 288, - T_MONITOR_PASSWORD = 289, - T_CITUS_CLUSTER_NAME = 290, - T_DEBIAN_CLUSTER = 291, - T_REPLICATION_QUORUM = 292, - T_REPLICATION_PASSWORD = 293, - T_EXTENSION_VERSION = 294, - T_BIND_SOURCE = 295, - T_FS_INIT = 296, - T_FS_SINGLE = 297, - T_FS_PRIMARY = 298, - T_FS_WAIT_PRIMARY = 299, - T_FS_WAIT_STANDBY = 300, - T_FS_DEMOTED = 301, - T_FS_DEMOTE_TIMEOUT = 302, - T_FS_DRAINING = 303, - T_FS_SECONDARY = 304, - T_FS_CATCHINGUP = 305, - T_FS_PREP_PROMOTION = 306, - T_FS_STOP_REPLICATION = 307, - T_FS_MAINTENANCE = 308, - T_FS_JOIN_PRIMARY = 309, - T_FS_APPLY_SETTINGS = 310, - T_FS_PREPARE_MAINTENANCE = 311, - T_FS_WAIT_MAINTENANCE = 312, - T_FS_REPORT_LSN = 313, - T_FS_FAST_FORWARD = 314, - T_FS_JOIN_SECONDARY = 315, - T_FS_DROPPED = 316, - T_EXEC = 317, - T_EXEC_FAILS = 318, - T_PG_AUTOCTL = 319, - T_WAIT = 320, - T_UNTIL = 321, - T_TIMEOUT = 322, - T_AND = 323, - T_IS = 324, - T_WITH = 325, - T_ASSERT = 326, - T_SQL = 327, - T_EXPECT = 328, - T_ERROR = 329, - T_PROMOTE = 330, - T_NETWORK = 331, - T_DISCONNECT = 332, - T_CONNECT = 333, - T_SLEEP = 334, - T_COMPOSE = 335, - T_DOWN = 336, - T_START = 337, - T_STOP = 338, - T_STOPPED = 339, - T_KILL = 340, - T_INJECT = 341, - T_STATE = 342, - T_ASSIGNED_STATE = 343, - T_IN = 344, - T_GROUP = 345, - T_LBRACE = 346, - T_RBRACE = 347, - T_COMMA = 348, - T_POSTGRES = 349, - T_STAYS = 350, - T_WHILE = 351, - T_THROUGH = 352, - T_SET = 353, - T_LOGS = 354, - T_NOT = 355, - T_CONTAINS = 356, - T_MATCHES = 357, - T_INTEGER = 358, - T_IDENT = 359, - T_STRING = 360, - T_BLOCK = 361, - T_SHELL_ARGS = 362 + T_SCENARIO = 259, + T_MONITOR = 260, + T_NODE = 261, + T_CITUS_COORDINATOR = 262, + T_CITUS_WORKER = 263, + T_SETUP = 264, + T_TEARDOWN = 265, + T_STEP = 266, + T_SEQUENCE = 267, + T_EQUALS = 268, + T_IMAGE = 269, + T_IMAGE_TARGET = 270, + T_SSL = 271, + T_AUTH = 272, + T_AUTH_METHOD = 273, + T_FORMATION = 274, + T_NUM_SYNC = 275, + T_COORDINATOR = 276, + T_WORKER = 277, + T_ASYNC = 278, + T_NO_MONITOR = 279, + T_LAUNCH = 280, + T_DEFERRED = 281, + T_IMMEDIATE = 282, + T_INITIALLY = 283, + T_VOLUME = 284, + T_LISTEN = 285, + T_CITUS_SECONDARY = 286, + T_CANDIDATE_PRIORITY = 287, + T_PORT = 288, + T_PASSWORD = 289, + T_MONITOR_PASSWORD = 290, + T_CITUS_CLUSTER_NAME = 291, + T_DEBIAN_CLUSTER = 292, + T_REPLICATION_QUORUM = 293, + T_REPLICATION_PASSWORD = 294, + T_EXTENSION_VERSION = 295, + T_BIND_SOURCE = 296, + T_FS_INIT = 297, + T_FS_SINGLE = 298, + T_FS_PRIMARY = 299, + T_FS_WAIT_PRIMARY = 300, + T_FS_WAIT_STANDBY = 301, + T_FS_DEMOTED = 302, + T_FS_DEMOTE_TIMEOUT = 303, + T_FS_DRAINING = 304, + T_FS_SECONDARY = 305, + T_FS_CATCHINGUP = 306, + T_FS_PREP_PROMOTION = 307, + T_FS_STOP_REPLICATION = 308, + T_FS_MAINTENANCE = 309, + T_FS_JOIN_PRIMARY = 310, + T_FS_APPLY_SETTINGS = 311, + T_FS_PREPARE_MAINTENANCE = 312, + T_FS_WAIT_MAINTENANCE = 313, + T_FS_REPORT_LSN = 314, + T_FS_FAST_FORWARD = 315, + T_FS_JOIN_SECONDARY = 316, + T_FS_DROPPED = 317, + T_EXEC = 318, + T_EXEC_FAILS = 319, + T_PG_AUTOCTL = 320, + T_WAIT = 321, + T_UNTIL = 322, + T_TIMEOUT = 323, + T_AND = 324, + T_IS = 325, + T_WITH = 326, + T_ASSERT = 327, + T_SQL = 328, + T_EXPECT = 329, + T_ERROR = 330, + T_PROMOTE = 331, + T_NETWORK = 332, + T_DISCONNECT = 333, + T_CONNECT = 334, + T_SLEEP = 335, + T_COMPOSE = 336, + T_DOWN = 337, + T_START = 338, + T_STOP = 339, + T_STOPPED = 340, + T_KILL = 341, + T_INJECT = 342, + T_STATE = 343, + T_ASSIGNED_STATE = 344, + T_IN = 345, + T_GROUP = 346, + T_LBRACE = 347, + T_RBRACE = 348, + T_COMMA = 349, + T_POSTGRES = 350, + T_STAYS = 351, + T_WHILE = 352, + T_THROUGH = 353, + T_SET = 354, + T_LOGS = 355, + T_NOT = 356, + T_CONTAINS = 357, + T_MATCHES = 358, + T_NODE_ACTIVE = 359, + T_MARK = 360, + T_HEALTHY = 361, + T_UNHEALTHY = 362, + T_STATES = 363, + T_INTEGER = 364, + T_IDENT = 365, + T_STRING = 366, + T_BLOCK = 367, + T_SHELL_ARGS = 368 }; #endif /* Tokens. */ #define T_CLUSTER 258 -#define T_MONITOR 259 -#define T_NODE 260 -#define T_CITUS_COORDINATOR 261 -#define T_CITUS_WORKER 262 -#define T_SETUP 263 -#define T_TEARDOWN 264 -#define T_STEP 265 -#define T_SEQUENCE 266 -#define T_EQUALS 267 -#define T_IMAGE 268 -#define T_IMAGE_TARGET 269 -#define T_SSL 270 -#define T_AUTH 271 -#define T_AUTH_METHOD 272 -#define T_FORMATION 273 -#define T_NUM_SYNC 274 -#define T_COORDINATOR 275 -#define T_WORKER 276 -#define T_ASYNC 277 -#define T_NO_MONITOR 278 -#define T_LAUNCH 279 -#define T_DEFERRED 280 -#define T_IMMEDIATE 281 -#define T_INITIALLY 282 -#define T_VOLUME 283 -#define T_LISTEN 284 -#define T_CITUS_SECONDARY 285 -#define T_CANDIDATE_PRIORITY 286 -#define T_PORT 287 -#define T_PASSWORD 288 -#define T_MONITOR_PASSWORD 289 -#define T_CITUS_CLUSTER_NAME 290 -#define T_DEBIAN_CLUSTER 291 -#define T_REPLICATION_QUORUM 292 -#define T_REPLICATION_PASSWORD 293 -#define T_EXTENSION_VERSION 294 -#define T_BIND_SOURCE 295 -#define T_FS_INIT 296 -#define T_FS_SINGLE 297 -#define T_FS_PRIMARY 298 -#define T_FS_WAIT_PRIMARY 299 -#define T_FS_WAIT_STANDBY 300 -#define T_FS_DEMOTED 301 -#define T_FS_DEMOTE_TIMEOUT 302 -#define T_FS_DRAINING 303 -#define T_FS_SECONDARY 304 -#define T_FS_CATCHINGUP 305 -#define T_FS_PREP_PROMOTION 306 -#define T_FS_STOP_REPLICATION 307 -#define T_FS_MAINTENANCE 308 -#define T_FS_JOIN_PRIMARY 309 -#define T_FS_APPLY_SETTINGS 310 -#define T_FS_PREPARE_MAINTENANCE 311 -#define T_FS_WAIT_MAINTENANCE 312 -#define T_FS_REPORT_LSN 313 -#define T_FS_FAST_FORWARD 314 -#define T_FS_JOIN_SECONDARY 315 -#define T_FS_DROPPED 316 -#define T_EXEC 317 -#define T_EXEC_FAILS 318 -#define T_PG_AUTOCTL 319 -#define T_WAIT 320 -#define T_UNTIL 321 -#define T_TIMEOUT 322 -#define T_AND 323 -#define T_IS 324 -#define T_WITH 325 -#define T_ASSERT 326 -#define T_SQL 327 -#define T_EXPECT 328 -#define T_ERROR 329 -#define T_PROMOTE 330 -#define T_NETWORK 331 -#define T_DISCONNECT 332 -#define T_CONNECT 333 -#define T_SLEEP 334 -#define T_COMPOSE 335 -#define T_DOWN 336 -#define T_START 337 -#define T_STOP 338 -#define T_STOPPED 339 -#define T_KILL 340 -#define T_INJECT 341 -#define T_STATE 342 -#define T_ASSIGNED_STATE 343 -#define T_IN 344 -#define T_GROUP 345 -#define T_LBRACE 346 -#define T_RBRACE 347 -#define T_COMMA 348 -#define T_POSTGRES 349 -#define T_STAYS 350 -#define T_WHILE 351 -#define T_THROUGH 352 -#define T_SET 353 -#define T_LOGS 354 -#define T_NOT 355 -#define T_CONTAINS 356 -#define T_MATCHES 357 -#define T_INTEGER 358 -#define T_IDENT 359 -#define T_STRING 360 -#define T_BLOCK 361 -#define T_SHELL_ARGS 362 +#define T_SCENARIO 259 +#define T_MONITOR 260 +#define T_NODE 261 +#define T_CITUS_COORDINATOR 262 +#define T_CITUS_WORKER 263 +#define T_SETUP 264 +#define T_TEARDOWN 265 +#define T_STEP 266 +#define T_SEQUENCE 267 +#define T_EQUALS 268 +#define T_IMAGE 269 +#define T_IMAGE_TARGET 270 +#define T_SSL 271 +#define T_AUTH 272 +#define T_AUTH_METHOD 273 +#define T_FORMATION 274 +#define T_NUM_SYNC 275 +#define T_COORDINATOR 276 +#define T_WORKER 277 +#define T_ASYNC 278 +#define T_NO_MONITOR 279 +#define T_LAUNCH 280 +#define T_DEFERRED 281 +#define T_IMMEDIATE 282 +#define T_INITIALLY 283 +#define T_VOLUME 284 +#define T_LISTEN 285 +#define T_CITUS_SECONDARY 286 +#define T_CANDIDATE_PRIORITY 287 +#define T_PORT 288 +#define T_PASSWORD 289 +#define T_MONITOR_PASSWORD 290 +#define T_CITUS_CLUSTER_NAME 291 +#define T_DEBIAN_CLUSTER 292 +#define T_REPLICATION_QUORUM 293 +#define T_REPLICATION_PASSWORD 294 +#define T_EXTENSION_VERSION 295 +#define T_BIND_SOURCE 296 +#define T_FS_INIT 297 +#define T_FS_SINGLE 298 +#define T_FS_PRIMARY 299 +#define T_FS_WAIT_PRIMARY 300 +#define T_FS_WAIT_STANDBY 301 +#define T_FS_DEMOTED 302 +#define T_FS_DEMOTE_TIMEOUT 303 +#define T_FS_DRAINING 304 +#define T_FS_SECONDARY 305 +#define T_FS_CATCHINGUP 306 +#define T_FS_PREP_PROMOTION 307 +#define T_FS_STOP_REPLICATION 308 +#define T_FS_MAINTENANCE 309 +#define T_FS_JOIN_PRIMARY 310 +#define T_FS_APPLY_SETTINGS 311 +#define T_FS_PREPARE_MAINTENANCE 312 +#define T_FS_WAIT_MAINTENANCE 313 +#define T_FS_REPORT_LSN 314 +#define T_FS_FAST_FORWARD 315 +#define T_FS_JOIN_SECONDARY 316 +#define T_FS_DROPPED 317 +#define T_EXEC 318 +#define T_EXEC_FAILS 319 +#define T_PG_AUTOCTL 320 +#define T_WAIT 321 +#define T_UNTIL 322 +#define T_TIMEOUT 323 +#define T_AND 324 +#define T_IS 325 +#define T_WITH 326 +#define T_ASSERT 327 +#define T_SQL 328 +#define T_EXPECT 329 +#define T_ERROR 330 +#define T_PROMOTE 331 +#define T_NETWORK 332 +#define T_DISCONNECT 333 +#define T_CONNECT 334 +#define T_SLEEP 335 +#define T_COMPOSE 336 +#define T_DOWN 337 +#define T_START 338 +#define T_STOP 339 +#define T_STOPPED 340 +#define T_KILL 341 +#define T_INJECT 342 +#define T_STATE 343 +#define T_ASSIGNED_STATE 344 +#define T_IN 345 +#define T_GROUP 346 +#define T_LBRACE 347 +#define T_RBRACE 348 +#define T_COMMA 349 +#define T_POSTGRES 350 +#define T_STAYS 351 +#define T_WHILE 352 +#define T_THROUGH 353 +#define T_SET 354 +#define T_LOGS 355 +#define T_NOT 356 +#define T_CONTAINS 357 +#define T_MATCHES 358 +#define T_NODE_ACTIVE 359 +#define T_MARK 360 +#define T_HEALTHY 361 +#define T_UNHEALTHY 362 +#define T_STATES 363 +#define T_INTEGER 364 +#define T_IDENT 365 +#define T_STRING 366 +#define T_BLOCK 367 +#define T_SHELL_ARGS 368 #if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED @@ -268,7 +280,7 @@ typedef union YYSTYPE } /* Line 1529 of yacc.c. */ -#line 270 "test_spec_parse.h" +#line 282 "test_spec_parse.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 997620cc5..adc6f47be 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -150,7 +150,7 @@ static TestNode *current_node = NULL; } /* ---- Outer-structure tokens (used in INITIAL lex state) ---- */ -%token T_CLUSTER T_MONITOR T_NODE T_CITUS_COORDINATOR T_CITUS_WORKER +%token T_CLUSTER T_SCENARIO T_MONITOR T_NODE T_CITUS_COORDINATOR T_CITUS_WORKER %token T_SETUP T_TEARDOWN T_STEP T_SEQUENCE %token T_EQUALS @@ -187,7 +187,7 @@ static TestNode *current_node = NULL; %token T_LBRACE T_RBRACE T_COMMA %token T_POSTGRES T_STAYS T_WHILE T_THROUGH T_SET %token T_LOGS T_NOT T_CONTAINS T_MATCHES -%token T_NODE_ACTIVE T_MARK T_HEALTHY T_UNHEALTHY +%token T_NODE_ACTIVE T_MARK T_HEALTHY T_UNHEALTHY T_STATES /* ---- Tokens with values ---- */ %token T_INTEGER @@ -216,6 +216,7 @@ spec: spec_item: cluster_block + | scenario_block | setup_block | teardown_block | named_step @@ -241,6 +242,43 @@ cluster_block: cluster_item_list T_RBRACE ; +/* ----------------------------------------------------------------------- + * scenario { } + * + * A monitor-API-only test scenario. Only the monitor service is + * provisioned; node names in the formation block are virtual (no + * containers are created for them). The node_active and mark_health + * commands are restricted to specs declared with this keyword. + * + * The lexer reuses the CLUSTER_BODY state for the scenario body so all + * the existing formation / node-name tokens are available. + * ----------------------------------------------------------------------- */ + +scenario_block: + T_SCENARIO T_LBRACE + { + current_spec->cluster.monitorApiOnly = true; + current_spec->cluster.withMonitor = true; + strlcpy(current_spec->cluster.ssl, "self-signed", + sizeof(current_spec->cluster.ssl)); + strlcpy(current_spec->cluster.auth, "trust", + sizeof(current_spec->cluster.auth)); + } + scenario_item_list T_RBRACE + ; + +scenario_item_list: + /* empty */ + | scenario_item_list scenario_item + ; + +scenario_item: + formation_block + | image_line + | ssl_line + | auth_line + ; + cluster_item_list: /* empty */ | cluster_item_list cluster_item @@ -1062,6 +1100,48 @@ assert_cmd: $$->timeoutSeconds = $6; free($2); free($5); } + | T_ASSERT T_STATES T_BLOCK + { + $$ = make_cmd(CMD_ASSERT_STATES); + /* T_BLOCK contains "node1: draining node2: prepare_promotion" */ + /* Parse name:state pairs inline */ + char *p = $3; + while (*p) + { + while (*p == ' ' || *p == '\t' || *p == '\n') p++; + if (*p == '\0') break; + /* name */ + char name[64] = { 0 }; + int ni = 0; + while (*p && *p != ':' && *p != ' ' && *p != '\t') + { + if (ni < 63) name[ni++] = *p; + p++; + } + while (*p == ' ' || *p == '\t') p++; + if (*p == ':') p++; + while (*p == ' ' || *p == '\t') p++; + /* state */ + char state[64] = { 0 }; + int si = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n') + { + if (si < 63) state[si++] = *p; + p++; + } + if (name[0] && state[0]) + { + int idx = $$->waitStateCount; + if (idx < PGAF_MAX_WAIT_STATES) + { + strlcpy($$->waitNodes[idx], name, sizeof($$->waitNodes[0])); + strlcpy($$->waitStates[idx], state, sizeof($$->waitStates[0])); + $$->waitStateCount++; + } + } + } + free($3); + } ; /* ----------------------------------------------------------------------- @@ -1379,6 +1459,11 @@ logs_cmd: node_active_cmd: T_NODE_ACTIVE T_BLOCK T_EXPECT T_BLOCK { + if (!current_spec->cluster.monitorApiOnly) + { + yyerror("node_active is only allowed inside a scenario { } block; " + "use a cluster { } block for full docker compose tests"); + } $$ = make_cmd(CMD_NODE_ACTIVE); /* $2 = "node2 reported: secondary lsn: 0/5A0 ..." */ strlcpy($$->args, $2, sizeof($$->args)); @@ -1396,6 +1481,11 @@ node_active_cmd: mark_health_cmd: T_MARK T_HEALTHY ':' T_IDENT { + if (!current_spec->cluster.monitorApiOnly) + { + yyerror("mark healthy/unhealthy is only allowed inside a scenario { } " + "block; use a cluster { } block for full docker compose tests"); + } $$ = make_cmd(CMD_MARK_HEALTH); strlcpy($$->service, $4, sizeof($$->service)); $$->markHealthy = true; @@ -1403,6 +1493,11 @@ mark_health_cmd: } | T_MARK T_UNHEALTHY ':' T_IDENT { + if (!current_spec->cluster.monitorApiOnly) + { + yyerror("mark healthy/unhealthy is only allowed inside a scenario { } " + "block; use a cluster { } block for full docker compose tests"); + } $$ = make_cmd(CMD_MARK_HEALTH); strlcpy($$->service, $4, sizeof($$->service)); $$->markHealthy = false; diff --git a/src/bin/pgaftest/test_spec_scan.c b/src/bin/pgaftest/test_spec_scan.c index 09618b246..1b5585958 100644 --- a/src/bin/pgaftest/test_spec_scan.c +++ b/src/bin/pgaftest/test_spec_scan.c @@ -181,7 +181,7 @@ extern FILE *yyin, *yyout; *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while (0) #define unput(c) yyunput(c, (yytext_ptr)) @@ -361,8 +361,8 @@ static void yynoreturn yy_fatal_error(const char *msg); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 147 -#define YY_END_OF_BUFFER 148 +#define YY_NUM_RULES 154 +#define YY_END_OF_BUFFER 155 /* This struct is not used in this scanner, * but its presence is necessary. */ @@ -371,137 +371,140 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[1162] = +static const flex_int16_t yy_accept[1196] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 148, 18, 17, 16, 18, 1, 12, 11, 13, 13, - 13, 13, 13, 13, 15, 147, 21, 20, 147, 19, - 55, 54, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 57, 58, 95, 94, 147, 93, 126, 137, 125, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 139, 140, - 143, 142, 144, 145, 146, 17, 0, 14, 1, 12, - 12, 13, 13, 13, 13, 13, 13, 13, 13, 21, - - 0, 56, 19, 55, 55, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 95, - 0, 138, 93, 137, 137, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 117, - 123, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 143, 142, 145, 13, 13, 13, 13, 13, - 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 25, 92, - 92, 92, 92, 122, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 134, 141, - 141, 141, 141, 141, 141, 141, 131, 141, 141, 103, - 141, 141, 141, 141, 141, 141, 141, 141, 13, 13, - 13, 4, 13, 13, 9, 13, 92, 92, 27, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 59, 92, 92, 92, 92, - 92, 92, 30, 92, 92, 47, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 112, 141, 141, 141, - 97, 141, 141, 141, 59, 141, 141, 116, 133, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 114, 141, 141, 141, 99, 141, - 124, 13, 13, 13, 13, 7, 13, 92, 33, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 46, 24, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 105, 141, 141, 141, 141, 121, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 110, 113, 118, 128, 141, 141, 141, 141, - 141, 100, 141, 141, 129, 13, 13, 13, 13, 13, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 37, 43, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 60, 92, 92, 92, - 42, 92, 92, 92, 92, 92, 92, 32, 141, 141, - 102, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 104, 141, 141, 132, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 60, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 13, 13, 2, 3, 13, 13, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 66, 92, 91, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 22, 92, 92, 92, - - 92, 61, 92, 92, 92, 92, 92, 92, 41, 92, - 92, 92, 92, 92, 92, 141, 141, 141, 141, 141, - 111, 109, 141, 141, 141, 66, 141, 141, 91, 141, - 141, 141, 141, 141, 141, 141, 141, 136, 107, 141, - 141, 141, 61, 106, 141, 141, 141, 141, 141, 115, - 130, 101, 141, 141, 141, 141, 141, 141, 13, 13, - 10, 8, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 38, 92, 92, 69, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 29, 35, 92, 92, 92, 92, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 141, 141, 141, 141, - 141, 135, 141, 141, 141, 69, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 127, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 13, - 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 28, 92, 39, 40, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 70, 92, 92, 92, 92, 92, - 92, 92, 92, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - - 141, 141, 141, 141, 141, 141, 70, 141, 141, 141, - 141, 141, 141, 141, 141, 13, 13, 92, 92, 92, - 92, 92, 71, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 34, - 92, 92, 92, 92, 92, 86, 85, 92, 92, 92, - 92, 92, 92, 92, 92, 141, 141, 141, 141, 71, - 141, 141, 108, 96, 141, 141, 141, 141, 141, 141, - 141, 98, 141, 141, 141, 141, 86, 85, 141, 141, - 141, 141, 141, 141, 141, 141, 13, 13, 92, 92, - 26, 53, 92, 92, 92, 31, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 92, 76, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 76, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 13, 6, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 88, 87, - 23, 78, 92, 77, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 63, 65, 92, 62, 64, 141, - 141, 141, 141, 141, 141, 88, 87, 78, 141, 77, - 141, 141, 141, 141, 141, 141, 141, 141, 63, 65, - - 141, 62, 64, 13, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 13, 80, 79, 92, 92, 92, 49, 68, - 67, 92, 90, 89, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 80, 79, 119, 141, 68, - 67, 90, 89, 141, 141, 141, 141, 141, 141, 141, - 141, 13, 92, 92, 44, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 141, 141, 141, - - 141, 141, 141, 141, 141, 141, 13, 92, 92, 92, - 36, 92, 92, 92, 92, 92, 92, 75, 74, 84, - 83, 141, 141, 141, 141, 141, 75, 74, 84, 83, - 5, 92, 92, 52, 92, 73, 92, 72, 92, 92, - 141, 141, 73, 141, 72, 45, 48, 92, 92, 92, - 50, 120, 141, 141, 82, 81, 92, 82, 81, 51, - 0 + 155, 19, 18, 17, 19, 1, 13, 12, 14, 14, + 14, 14, 14, 14, 16, 154, 22, 21, 154, 20, + 56, 55, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 58, 59, 96, 95, 154, 94, 127, 144, 143, 126, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 146, 147, 150, 149, 151, 152, 153, 18, 0, 15, + 1, 13, 13, 14, 14, 14, 14, 14, 14, 14, + + 14, 14, 22, 0, 57, 20, 56, 56, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 96, 0, 145, 94, 144, 144, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 118, 124, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 150, 149, 152, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 26, 93, 93, 93, 93, 123, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 135, 148, 148, 148, + 148, 148, 148, 148, 132, 148, 148, 104, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 14, 14, 14, + 5, 14, 14, 14, 10, 14, 93, 93, 28, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 60, 93, 93, 93, 93, + 93, 93, 31, 93, 93, 48, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 113, 148, 148, 148, + 98, 148, 148, 148, 148, 60, 148, 148, 117, 134, + 148, 139, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 115, 148, 148, + 148, 148, 100, 148, 125, 14, 14, 14, 14, 14, + 8, 14, 93, 34, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 93, 47, + 25, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 106, 148, 148, + 148, 148, 122, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 111, + 114, 119, 129, 148, 148, 148, 148, 148, 148, 101, + 148, 148, 130, 14, 14, 14, 14, 14, 14, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 38, 44, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 61, 93, 93, 93, 43, + 93, 93, 93, 93, 93, 93, 33, 148, 148, 103, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 105, 148, 148, 148, 133, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 61, 142, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 14, 14, 2, 4, 14, + 14, 14, 93, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 67, 93, 92, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 23, 93, 93, 93, 93, 62, 93, 93, 93, 93, + 93, 93, 42, 93, 93, 93, 93, 93, 93, 148, + 148, 148, 148, 148, 112, 110, 148, 148, 148, 67, + 148, 148, 92, 148, 148, 148, 140, 148, 148, 148, + 148, 148, 137, 108, 148, 148, 148, 148, 62, 107, + 148, 148, 148, 148, 148, 116, 131, 102, 148, 148, + 148, 148, 148, 148, 148, 14, 14, 3, 11, 9, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + + 39, 93, 93, 70, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 30, 36, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 148, 148, 148, 148, 148, 136, + 148, 148, 148, 70, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 128, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 14, + 14, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 29, 93, 40, 41, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 71, 93, 93, 93, 93, 93, + 93, 93, 93, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 71, 148, 148, + 141, 148, 148, 148, 148, 148, 148, 14, 14, 93, + 93, 93, 93, 93, 72, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 35, 93, 93, 93, 93, 93, 87, 86, 93, + 93, 93, 93, 93, 93, 93, 93, 148, 148, 148, + 148, 72, 148, 148, 109, 97, 148, 148, 148, 148, + + 148, 148, 148, 148, 99, 148, 148, 148, 148, 87, + 86, 148, 148, 148, 148, 148, 148, 148, 148, 14, + 14, 93, 93, 27, 54, 93, 93, 93, 32, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 77, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 77, 138, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 14, 7, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 89, 88, 24, 79, 93, 78, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 64, 66, + 93, 63, 65, 148, 148, 148, 148, 148, 148, 89, + 88, 79, 148, 78, 148, 148, 148, 148, 148, 148, + 148, 148, 64, 66, 148, 63, 65, 14, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 14, 81, 80, 93, + 93, 93, 50, 69, 68, 93, 91, 90, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 81, + + 80, 120, 148, 69, 68, 91, 90, 148, 148, 148, + 148, 148, 148, 148, 148, 14, 93, 93, 45, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 14, 93, 93, 93, 37, 93, 93, 93, 93, 93, + 93, 76, 75, 85, 84, 148, 148, 148, 148, 148, + 76, 75, 85, 84, 6, 93, 93, 53, 93, 74, + 93, 73, 93, 93, 148, 148, 74, 148, 73, 46, + 49, 93, 93, 93, 51, 121, 148, 148, 83, 82, + 93, 83, 82, 52, 0 }; static const YY_CHAR yy_ec[256] = @@ -512,15 +515,15 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 8, 1, 1, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, - 10, 1, 1, 1, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, - 1, 1, 1, 1, 13, 1, 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, 11, 39, 1, 40, 1, 1, 1, 1, 1, + 9, 9, 9, 9, 9, 9, 9, 10, 1, 1, + 11, 1, 1, 1, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 13, 12, 12, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 14, 1, 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, 12, 40, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -537,575 +540,592 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 }; -static const YY_CHAR yy_meta[41] = +static const YY_CHAR yy_meta[42] = { 0, 1, 2, 3, 1, 1, 1, 1, 4, 4, 1, + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, + 1 }; -static const flex_int16_t yy_base[1175] = +static const flex_int16_t yy_base[1209] = { 0, - 0, 0, 40, 0, 80, 0, 119, 121, 1250, 1249, - 1251, 1254, 123, 1254, 1245, 0, 117, 1254, 0, 106, - 1221, 1220, 112, 1229, 1254, 1254, 130, 1254, 1241, 0, - 124, 1254, 0, 106, 1223, 125, 119, 1207, 127, 1212, - 116, 1214, 130, 132, 120, 137, 1223, 139, 1212, 145, - 1254, 1254, 160, 1254, 1234, 0, 1254, 154, 1254, 0, - 147, 153, 160, 138, 1224, 1206, 153, 1208, 1213, 1206, - 1219, 159, 164, 1214, 171, 176, 1204, 185, 1254, 1254, - 0, 1228, 1254, 0, 1254, 198, 1224, 1254, 0, 196, - 1254, 0, 1195, 1193, 1199, 1208, 179, 1206, 1209, 209, - - 1217, 1254, 0, 205, 1254, 0, 1192, 1182, 1186, 1191, - 183, 1184, 1188, 200, 204, 1182, 1182, 1182, 1184, 144, - 1189, 1188, 1175, 1176, 1185, 1179, 186, 1179, 1172, 1172, - 202, 1173, 1185, 1173, 1174, 1170, 1172, 1174, 1164, 219, - 1189, 1254, 0, 213, 1254, 0, 1176, 1163, 1159, 200, - 203, 1164, 1157, 1152, 220, 1156, 213, 1154, 1157, 213, - 0, 1162, 1158, 1162, 216, 1148, 1147, 1166, 1146, 222, - 1148, 223, 1149, 1157, 1149, 227, 1142, 1146, 1138, 1148, - 1147, 1135, 0, 1165, 0, 1132, 1133, 1142, 1145, 1128, - 1127, 1131, 1128, 1133, 1130, 1135, 1138, 1137, 1137, 1118, - - 1120, 1128, 1131, 1120, 1125, 1117, 1127, 1111, 1117, 1108, - 1121, 1122, 1106, 1111, 1110, 1103, 1108, 1112, 1107, 1114, - 1123, 1098, 1096, 1099, 1101, 218, 1098, 1105, 0, 1095, - 1089, 1089, 1097, 0, 1095, 229, 1102, 1102, 1088, 225, - 1088, 1099, 1087, 1091, 1083, 1083, 1094, 1091, 1075, 1073, - 1073, 1087, 1077, 1078, 1070, 1074, 1084, 1063, 0, 1084, - 1064, 1067, 1069, 1068, 1065, 1064, 0, 1071, 1072, 0, - 226, 1060, 1060, 1069, 1064, 1052, 1059, 1062, 1050, 1048, - 1047, 0, 1061, 1049, 0, 1060, 1038, 1059, 1066, 1065, - 1050, 1050, 1038, 1052, 1054, 1036, 1033, 1038, 1035, 1036, - - 252, 1048, 1032, 1042, 1042, 1036, 253, 1041, 1038, 1022, - 1021, 1025, 0, 1020, 1015, 0, 1036, 1035, 1026, 1016, - 1019, 1020, 254, 1018, 255, 1025, 1004, 1010, 1020, 1017, - 1017, 1009, 1018, 1021, 1001, 1005, 0, 1005, 1002, 999, - 1021, 1012, 261, 998, 0, 1010, 262, 0, 0, 992, - 1003, 995, 988, 1001, 1006, 1005, 990, 986, 989, 990, - 985, 980, 994, 979, 263, 976, 981, 983, 264, 989, - 0, 998, 987, 976, 976, 0, 974, 265, 0, 975, - 968, 982, 976, 989, 974, 968, 963, 975, 970, 973, - 958, 970, 969, 954, 0, 978, 963, 970, 250, 252, - - 962, 955, 963, 952, 952, 940, 949, 945, 944, 958, - 940, 955, 953, 939, 938, 950, 949, 259, 261, 935, - 281, 932, 937, 946, 940, 929, 944, 937, 940, 930, - 934, 937, 0, 935, 920, 933, 932, 0, 917, 266, - 267, 931, 930, 916, 913, 914, 913, 912, 909, 908, - 923, 921, 0, 0, 0, 0, 907, 906, 918, 915, - 900, 0, 271, 275, 0, 270, 902, 901, 915, 894, - 897, 896, 909, 898, 911, 897, 286, 896, 914, 903, - 297, 893, 902, 896, 889, 888, 893, 881, 899, 887, - 880, 892, 878, 890, 0, 0, 880, 875, 883, 877, - - 872, 884, 863, 886, 300, 885, 0, 880, 879, 879, - 0, 881, 863, 860, 878, 860, 857, 0, 857, 856, - 0, 869, 872, 858, 866, 850, 855, 303, 854, 853, - 862, 864, 0, 849, 848, 0, 844, 856, 842, 854, - 844, 838, 845, 840, 849, 848, 827, 846, 304, 849, - 0, 844, 843, 843, 838, 825, 843, 825, 822, 840, - 822, 819, 823, 822, 0, 0, 831, 821, 829, 828, - 812, 810, 810, 822, 816, 822, 825, 822, 820, 803, - 802, 0, 814, 0, 805, 801, 800, 802, 815, 795, - 802, 804, 809, 802, 807, 808, 813, 787, 803, 801, - - 311, 0, 784, 791, 790, 783, 784, 783, 0, 789, - 788, 795, 786, 785, 792, 787, 786, 786, 769, 781, - 0, 0, 768, 766, 765, 0, 779, 776, 0, 773, - 763, 762, 770, 775, 768, 773, 774, 0, 0, 771, - 754, 313, 0, 0, 760, 759, 752, 753, 752, 0, - 0, 0, 758, 757, 764, 755, 754, 761, 746, 742, - 0, 0, 739, 738, 749, 738, 750, 733, 732, 749, - 731, 738, 0, 740, 739, 0, 733, 723, 722, 729, - 721, 733, 145, 164, 225, 228, 252, 282, 286, 294, - 0, 0, 299, 301, 301, 297, 299, 294, 308, 309, - - 308, 310, 310, 311, 313, 313, 308, 309, 335, 326, - 311, 0, 324, 325, 332, 0, 324, 314, 315, 326, - 325, 328, 327, 329, 324, 0, 332, 333, 328, 331, - 326, 340, 341, 340, 342, 342, 343, 345, 345, 342, - 350, 342, 343, 349, 362, 371, 351, 349, 354, 355, - 350, 359, 360, 379, 374, 375, 0, 370, 0, 0, - 377, 365, 379, 367, 379, 382, 366, 384, 368, 386, - 370, 374, 376, 377, 0, 383, 384, 374, 394, 392, - 377, 397, 395, 380, 381, 383, 408, 388, 392, 393, - 387, 389, 408, 409, 410, 398, 412, 400, 412, 404, - - 416, 400, 418, 402, 407, 408, 0, 414, 415, 405, - 425, 423, 408, 428, 426, 427, 427, 424, 425, 431, - 431, 421, 0, 418, 425, 422, 422, 437, 438, 422, - 427, 428, 442, 430, 445, 432, 447, 447, 434, 0, - 445, 440, 447, 442, 444, 0, 0, 456, 457, 456, - 444, 461, 459, 447, 464, 458, 459, 449, 454, 0, - 466, 467, 0, 0, 455, 456, 457, 472, 459, 474, - 474, 0, 471, 466, 473, 468, 0, 0, 481, 482, - 481, 469, 486, 484, 472, 489, 483, 475, 480, 481, - 0, 0, 478, 492, 494, 0, 479, 485, 486, 497, - - 499, 500, 485, 481, 506, 483, 508, 0, 491, 497, - 499, 499, 501, 520, 515, 516, 504, 494, 495, 507, - 497, 498, 510, 511, 525, 509, 513, 514, 526, 527, - 507, 532, 509, 534, 0, 522, 524, 524, 526, 539, - 540, 528, 518, 519, 531, 521, 522, 534, 0, 542, - 543, 542, 534, 552, 549, 534, 535, 539, 0, 0, - 0, 0, 540, 0, 541, 537, 541, 547, 543, 549, - 549, 547, 548, 568, 0, 0, 569, 0, 0, 564, - 565, 553, 565, 554, 555, 0, 0, 0, 559, 0, - 560, 559, 565, 561, 567, 563, 564, 584, 0, 0, - - 585, 0, 0, 586, 569, 570, 575, 596, 574, 575, - 574, 575, 577, 572, 573, 584, 595, 581, 597, 583, - 603, 584, 597, 598, 594, 595, 591, 592, 607, 598, - 594, 595, 591, 592, 613, 599, 615, 601, 613, 614, - 610, 611, 606, 0, 0, 609, 614, 604, 0, 0, - 0, 621, 0, 0, 613, 618, 624, 620, 626, 617, - 622, 623, 624, 637, 638, 0, 0, 0, 624, 0, - 0, 0, 0, 629, 635, 631, 637, 632, 633, 646, - 647, 636, 643, 652, 0, 639, 651, 655, 642, 657, - 644, 641, 643, 648, 649, 659, 660, 657, 666, 653, - - 668, 655, 657, 658, 668, 669, 657, 656, 664, 664, - 0, 665, 666, 667, 668, 660, 663, 0, 0, 0, - 0, 665, 672, 673, 674, 675, 0, 0, 0, 0, - 0, 665, 686, 0, 689, 0, 690, 0, 679, 682, - 671, 694, 0, 695, 0, 0, 0, 694, 695, 683, - 0, 0, 697, 698, 0, 0, 700, 0, 0, 0, - 1254, 717, 721, 725, 729, 728, 733, 737, 736, 741, - 745, 744, 749, 753 + 0, 0, 41, 0, 82, 0, 122, 124, 1285, 1284, + 1286, 1289, 126, 1289, 1280, 0, 120, 1289, 0, 108, + 1255, 1254, 118, 1263, 1289, 1289, 134, 1289, 1276, 0, + 130, 1289, 0, 111, 1257, 125, 113, 1241, 127, 1246, + 122, 1248, 132, 136, 129, 142, 1257, 143, 1246, 144, + 1289, 1289, 165, 1289, 1269, 0, 1289, 159, 1289, 1289, + 0, 150, 146, 162, 150, 1258, 1240, 1252, 151, 1241, + 1246, 1239, 1252, 141, 166, 1247, 170, 177, 1237, 187, + 1289, 1289, 0, 1262, 1289, 0, 1289, 201, 1258, 1289, + 0, 198, 1289, 0, 1228, 1226, 1232, 1241, 1239, 181, + + 1238, 1241, 204, 1250, 1289, 0, 204, 1289, 0, 1224, + 1214, 1218, 1223, 186, 1216, 1220, 170, 201, 1214, 1214, + 1214, 1216, 206, 1221, 1220, 1207, 1208, 1217, 1211, 210, + 1211, 1204, 1204, 200, 1205, 1217, 1205, 1206, 1202, 1204, + 1206, 1196, 220, 1222, 1289, 0, 216, 1289, 0, 1208, + 1195, 1191, 198, 207, 1196, 1189, 1184, 212, 1188, 217, + 1186, 1189, 1202, 215, 0, 1193, 1189, 1193, 219, 1179, + 222, 1198, 1178, 225, 1180, 226, 1181, 1189, 1181, 230, + 1174, 1178, 224, 1181, 1180, 1168, 0, 1199, 0, 1165, + 1166, 1175, 1178, 1168, 1160, 1159, 1163, 1160, 1165, 1162, + + 1167, 1170, 1169, 1169, 1150, 1152, 1160, 1163, 1152, 1157, + 1149, 1159, 1143, 1149, 1140, 1153, 1154, 1138, 1143, 1142, + 1135, 1140, 1144, 1139, 1146, 1156, 1130, 1128, 1131, 1133, + 226, 1130, 1137, 0, 1127, 1121, 1121, 1129, 0, 1127, + 238, 1134, 1134, 1120, 234, 1120, 1131, 1119, 1123, 1115, + 1115, 1126, 1123, 1107, 1105, 1113, 1104, 1118, 1108, 1109, + 1101, 1105, 1107, 1114, 1093, 1110, 0, 1113, 1093, 1096, + 1098, 1097, 1094, 1093, 0, 1100, 1101, 0, 231, 1089, + 1089, 1098, 1097, 1092, 1080, 1087, 1090, 1078, 1076, 1075, + 0, 1093, 1088, 1076, 0, 1087, 1065, 1086, 1094, 1093, + + 1077, 1077, 1065, 1079, 1081, 1063, 1060, 1065, 1062, 1063, + 258, 1075, 1059, 1069, 1069, 1063, 259, 1068, 1065, 1049, + 1048, 1052, 0, 1047, 1042, 0, 1063, 1062, 1053, 1043, + 1046, 1047, 261, 1045, 263, 1052, 1031, 1037, 1047, 1044, + 1044, 1036, 1045, 1048, 1028, 1032, 0, 1032, 1029, 1026, + 1049, 1039, 266, 1025, 1020, 0, 1036, 268, 0, 0, + 1018, 0, 1029, 1021, 1035, 1013, 1026, 1031, 1030, 1015, + 1011, 1014, 1015, 1010, 1005, 1019, 1004, 270, 1001, 1006, + 1019, 1007, 271, 1013, 0, 1023, 1011, 1000, 996, 999, + 0, 997, 273, 0, 998, 991, 1005, 999, 1013, 997, + + 991, 986, 998, 993, 996, 981, 993, 992, 977, 0, + 1002, 986, 993, 253, 259, 985, 978, 986, 975, 975, + 963, 972, 968, 967, 981, 963, 978, 976, 962, 961, + 973, 972, 263, 268, 958, 280, 955, 960, 969, 963, + 952, 967, 960, 963, 953, 957, 960, 0, 958, 943, + 956, 955, 0, 952, 939, 269, 273, 953, 952, 938, + 954, 934, 935, 934, 933, 930, 929, 944, 942, 0, + 0, 927, 0, 927, 926, 938, 935, 920, 928, 0, + 277, 278, 0, 280, 921, 920, 928, 933, 912, 915, + 914, 927, 916, 929, 915, 292, 914, 933, 921, 304, + + 911, 920, 914, 907, 906, 911, 899, 917, 905, 898, + 910, 896, 908, 0, 0, 898, 893, 901, 895, 890, + 902, 881, 904, 305, 903, 0, 898, 897, 897, 0, + 899, 881, 878, 896, 878, 875, 0, 875, 874, 0, + 887, 890, 876, 884, 868, 873, 306, 872, 871, 880, + 882, 0, 867, 866, 855, 0, 861, 873, 859, 871, + 861, 855, 862, 869, 856, 865, 864, 843, 862, 307, + 865, 0, 0, 860, 859, 859, 854, 841, 840, 858, + 840, 837, 855, 837, 834, 838, 837, 0, 0, 836, + 845, 835, 843, 842, 826, 824, 824, 836, 830, 836, + + 839, 836, 834, 817, 816, 0, 828, 0, 819, 815, + 814, 816, 829, 809, 816, 818, 823, 816, 821, 822, + 828, 801, 817, 815, 315, 0, 798, 805, 804, 797, + 798, 797, 0, 803, 802, 809, 800, 799, 806, 801, + 800, 800, 783, 795, 0, 0, 782, 780, 779, 0, + 793, 790, 0, 787, 777, 776, 0, 784, 789, 782, + 787, 788, 0, 0, 768, 784, 767, 318, 0, 0, + 773, 772, 765, 766, 765, 0, 0, 0, 772, 770, + 768, 772, 763, 227, 249, 287, 295, 0, 0, 0, + 294, 296, 309, 301, 315, 300, 301, 320, 304, 313, + + 0, 317, 318, 0, 314, 306, 307, 317, 314, 328, + 309, 322, 321, 324, 323, 325, 324, 326, 0, 0, + 329, 330, 335, 328, 329, 324, 338, 339, 338, 340, + 340, 341, 343, 343, 338, 339, 366, 356, 341, 0, + 354, 355, 362, 0, 354, 344, 345, 356, 355, 358, + 357, 359, 365, 355, 0, 363, 364, 359, 362, 357, + 371, 372, 360, 372, 374, 374, 375, 377, 377, 374, + 382, 374, 375, 381, 394, 404, 383, 381, 386, 387, + 382, 391, 392, 412, 406, 407, 0, 402, 0, 0, + 409, 397, 411, 399, 411, 414, 398, 416, 400, 418, + + 402, 406, 408, 409, 0, 415, 416, 406, 426, 424, + 409, 429, 427, 412, 413, 415, 441, 420, 424, 425, + 419, 421, 440, 441, 442, 430, 444, 432, 444, 426, + 437, 449, 433, 451, 435, 440, 441, 0, 447, 448, + 0, 438, 458, 456, 441, 461, 459, 460, 460, 457, + 458, 464, 464, 454, 0, 451, 458, 455, 455, 470, + 471, 455, 460, 461, 475, 463, 478, 465, 480, 480, + 467, 0, 478, 473, 480, 475, 477, 0, 0, 489, + 490, 489, 477, 494, 492, 480, 497, 491, 492, 482, + 487, 0, 499, 500, 0, 0, 488, 489, 490, 505, + + 492, 507, 507, 508, 0, 505, 500, 507, 502, 0, + 0, 515, 516, 515, 503, 520, 518, 506, 523, 517, + 509, 514, 515, 0, 0, 512, 526, 528, 0, 513, + 519, 520, 531, 533, 534, 519, 515, 540, 517, 542, + 0, 525, 531, 533, 533, 535, 555, 549, 550, 538, + 528, 529, 541, 531, 532, 544, 545, 559, 543, 547, + 548, 560, 561, 541, 566, 543, 568, 0, 0, 556, + 558, 558, 560, 573, 574, 562, 552, 553, 565, 555, + 556, 568, 0, 576, 577, 576, 568, 586, 583, 568, + 569, 573, 0, 0, 0, 0, 574, 0, 575, 571, + + 575, 581, 577, 583, 583, 581, 582, 602, 0, 0, + 603, 0, 0, 598, 599, 587, 599, 588, 589, 0, + 0, 0, 593, 0, 594, 593, 599, 595, 601, 597, + 598, 618, 0, 0, 619, 0, 0, 620, 603, 604, + 609, 631, 608, 609, 608, 609, 611, 606, 607, 618, + 629, 615, 631, 617, 637, 618, 631, 632, 628, 629, + 625, 626, 641, 632, 628, 629, 625, 626, 647, 633, + 649, 635, 647, 648, 644, 645, 640, 0, 0, 643, + 648, 638, 0, 0, 0, 655, 0, 0, 647, 652, + 658, 654, 660, 651, 656, 657, 658, 671, 672, 0, + + 0, 0, 658, 0, 0, 0, 0, 663, 669, 665, + 671, 666, 667, 680, 681, 670, 677, 686, 0, 673, + 685, 689, 676, 691, 678, 675, 677, 682, 683, 693, + 694, 691, 700, 687, 702, 689, 691, 692, 702, 703, + 691, 690, 698, 698, 0, 699, 700, 701, 702, 694, + 697, 0, 0, 0, 0, 699, 706, 707, 708, 709, + 0, 0, 0, 0, 0, 699, 720, 0, 723, 0, + 724, 0, 713, 716, 705, 728, 0, 729, 0, 0, + 0, 728, 729, 717, 0, 0, 731, 732, 0, 0, + 734, 0, 0, 0, 1289, 752, 756, 760, 764, 763, + + 768, 772, 771, 776, 780, 779, 784, 788 }; -static const flex_int16_t yy_def[1175] = +static const flex_int16_t yy_def[1209] = { 0, - 1161, 1, 1161, 3, 1161, 5, 1162, 1162, 1163, 1163, - 1161, 1161, 1161, 1161, 1164, 1165, 1161, 1161, 1166, 1166, - 1166, 1166, 1166, 1166, 1161, 1161, 1161, 1161, 1167, 1168, - 1161, 1161, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1161, 1161, 1161, 1161, 1170, 1171, 1161, 1161, 1161, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1161, 1161, - 1173, 1161, 1161, 1174, 1161, 1161, 1164, 1161, 1165, 1161, - 1161, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1161, - - 1167, 1161, 1168, 1161, 1161, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1161, - 1170, 1161, 1171, 1161, 1161, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1173, 1161, 1174, 1166, 1166, 1166, 1166, 1166, - 1166, 1166, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, - 1166, 1166, 1166, 1166, 1166, 1166, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1166, 1166, 1166, 1166, 1166, 1166, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1166, 1166, 1166, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1166, 1166, 1166, 1166, 1166, 1166, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, - 1166, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, - 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - - 1172, 1172, 1172, 1166, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, - 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1172, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, - - 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1169, 1169, 1169, - 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, - 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, - 1172, 1172, 1172, 1172, 1172, 1169, 1169, 1169, 1169, 1169, - 1169, 1172, 1172, 1172, 1169, 1169, 1169, 1172, 1172, 1169, - 0, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161 + 1195, 1, 1195, 3, 1195, 5, 1196, 1196, 1197, 1197, + 1195, 1195, 1195, 1195, 1198, 1199, 1195, 1195, 1200, 1200, + 1200, 1200, 1200, 1200, 1195, 1195, 1195, 1195, 1201, 1202, + 1195, 1195, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1195, 1195, 1195, 1195, 1204, 1205, 1195, 1195, 1195, 1195, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1195, 1195, 1207, 1195, 1195, 1208, 1195, 1195, 1198, 1195, + 1199, 1195, 1195, 1200, 1200, 1200, 1200, 1200, 1200, 1200, + + 1200, 1200, 1195, 1201, 1195, 1202, 1195, 1195, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1195, 1204, 1195, 1205, 1195, 1195, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1195, 1208, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, 1200, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, + 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, + 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1200, 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, + + 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1206, 1200, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, + 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, + 1206, 1206, 1206, 1206, 1200, 1203, 1203, 1203, 1203, 1203, + 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1203, + 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1203, 1203, + 1203, 1206, 1206, 1203, 0, 1195, 1195, 1195, 1195, 1195, + + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195 }; -static const flex_int16_t yy_nxt[1295] = +static const flex_int16_t yy_nxt[1331] = { 0, - 12, 13, 14, 13, 15, 16, 12, 12, 17, 18, - 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 21, 22, 19, 19, 19, - 19, 23, 24, 19, 19, 19, 19, 19, 25, 12, - 26, 27, 28, 27, 29, 30, 26, 26, 31, 32, - 33, 33, 33, 34, 35, 36, 37, 38, 39, 40, - 33, 41, 42, 33, 43, 44, 45, 33, 46, 33, - 47, 48, 33, 33, 49, 50, 33, 33, 51, 52, - 26, 53, 54, 53, 55, 56, 57, 26, 58, 59, - 60, 60, 60, 61, 60, 62, 63, 64, 65, 66, - - 60, 67, 68, 69, 70, 71, 72, 60, 73, 60, - 74, 75, 76, 77, 60, 78, 60, 60, 79, 80, - 82, 83, 82, 83, 86, 90, 86, 93, 91, 97, - 94, 100, 104, 100, 107, 105, 114, 108, 111, 109, - 117, 120, 121, 123, 98, 125, 112, 127, 91, 115, - 129, 124, 113, 128, 118, 105, 133, 211, 138, 126, - 134, 140, 144, 140, 130, 145, 150, 131, 156, 212, - 135, 136, 139, 147, 157, 148, 166, 152, 149, 160, - 151, 153, 760, 168, 161, 145, 167, 154, 172, 761, - 155, 169, 173, 219, 170, 174, 177, 178, 180, 86, - - 175, 86, 220, 176, 90, 181, 182, 91, 190, 198, - 100, 191, 100, 104, 202, 199, 105, 205, 203, 224, - 140, 144, 140, 225, 145, 204, 237, 91, 239, 240, - 247, 206, 238, 244, 251, 252, 105, 256, 266, 262, - 271, 248, 319, 263, 145, 320, 328, 245, 257, 264, - 329, 333, 762, 763, 272, 267, 362, 334, 363, 392, - 399, 414, 418, 364, 393, 400, 415, 419, 436, 440, - 457, 463, 471, 437, 441, 458, 464, 472, 491, 764, - 493, 492, 416, 494, 512, 563, 515, 513, 519, 516, - 514, 459, 517, 520, 537, 539, 557, 538, 540, 558, - - 560, 575, 559, 561, 580, 564, 562, 604, 765, 581, - 624, 645, 605, 582, 766, 625, 646, 576, 693, 626, - 727, 767, 772, 694, 768, 728, 770, 769, 773, 771, - 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, - 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, - 794, 795, 796, 797, 798, 799, 800, 801, 803, 805, - 802, 804, 806, 807, 808, 809, 810, 811, 812, 813, - 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, - 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, - - 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, - 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, - 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, - 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, - 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, - 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, - 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, - 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, - 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, - 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, - - 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, - 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, - 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, - 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, - 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, - 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, - 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, - 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, - 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, - - 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, - 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, - 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, - 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, - 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, - 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, - 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, - 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, - 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, - 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, - - 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, - 1154, 1155, 1156, 1157, 1158, 1159, 1160, 81, 81, 81, - 81, 84, 84, 84, 84, 87, 87, 87, 87, 89, - 89, 92, 89, 101, 101, 101, 101, 103, 103, 106, - 103, 141, 141, 141, 141, 143, 143, 146, 143, 183, - 759, 758, 183, 185, 185, 757, 185, 756, 755, 754, - 753, 752, 751, 750, 749, 748, 747, 746, 745, 744, - 743, 742, 741, 740, 739, 738, 737, 736, 735, 734, - 733, 732, 731, 730, 729, 726, 725, 724, 723, 722, - 721, 720, 719, 718, 717, 716, 715, 714, 713, 712, - - 711, 710, 709, 708, 707, 706, 705, 704, 703, 702, - 701, 700, 699, 698, 697, 696, 695, 692, 691, 690, - 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, - 679, 678, 677, 676, 675, 674, 673, 672, 671, 670, - 669, 668, 667, 666, 665, 664, 663, 662, 661, 660, - 659, 658, 657, 656, 655, 654, 653, 652, 651, 650, - 649, 648, 647, 644, 643, 642, 641, 640, 639, 638, - 637, 636, 635, 634, 633, 632, 631, 630, 629, 628, - 627, 623, 622, 621, 620, 619, 618, 617, 616, 615, - 614, 613, 612, 611, 610, 609, 608, 607, 606, 603, - - 602, 601, 600, 599, 598, 597, 596, 595, 594, 593, - 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, - 579, 578, 577, 574, 573, 572, 571, 570, 569, 568, - 567, 566, 565, 556, 555, 554, 553, 552, 551, 550, - 549, 548, 547, 546, 545, 544, 543, 542, 541, 536, - 535, 534, 533, 532, 531, 530, 529, 528, 527, 526, - 525, 524, 523, 522, 521, 518, 511, 510, 509, 508, - 507, 506, 505, 504, 503, 502, 501, 500, 499, 498, - 497, 496, 495, 490, 489, 488, 487, 486, 485, 484, - 483, 482, 481, 480, 479, 478, 477, 476, 475, 474, - - 473, 470, 469, 468, 467, 466, 465, 462, 461, 460, - 456, 455, 454, 453, 452, 451, 450, 449, 448, 447, - 446, 445, 444, 443, 442, 439, 438, 435, 434, 433, - 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, - 422, 421, 420, 417, 413, 412, 411, 410, 409, 408, - 407, 406, 405, 404, 403, 402, 401, 398, 397, 396, - 395, 394, 391, 390, 389, 388, 387, 386, 385, 384, - 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, - 373, 372, 371, 370, 369, 368, 367, 366, 365, 361, - 360, 359, 358, 357, 356, 355, 354, 353, 352, 351, - - 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, - 340, 339, 338, 337, 336, 335, 332, 331, 330, 327, - 326, 325, 324, 323, 322, 321, 318, 317, 316, 315, - 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, - 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, - 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, - 284, 283, 282, 281, 280, 279, 184, 278, 277, 276, - 275, 274, 273, 270, 269, 268, 265, 261, 260, 259, - 258, 255, 254, 253, 250, 249, 246, 243, 242, 241, - 236, 235, 234, 142, 233, 232, 231, 230, 229, 228, - - 227, 226, 223, 222, 221, 218, 217, 216, 215, 214, - 213, 210, 209, 208, 207, 201, 200, 197, 196, 195, - 194, 102, 193, 192, 189, 188, 187, 186, 88, 184, - 179, 171, 165, 164, 163, 162, 159, 158, 142, 137, - 132, 122, 119, 116, 110, 102, 99, 96, 95, 88, - 1161, 85, 85, 11, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161 + 12, 13, 14, 13, 15, 16, 12, 12, 17, 12, + 18, 19, 19, 19, 19, 19, 20, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 21, 22, 19, 19, + 19, 19, 23, 24, 19, 19, 19, 19, 19, 25, + 12, 26, 27, 28, 27, 29, 30, 26, 26, 31, + 26, 32, 33, 33, 33, 34, 35, 36, 37, 38, + 39, 40, 33, 41, 42, 33, 43, 44, 45, 33, + 46, 33, 47, 48, 33, 33, 49, 50, 33, 33, + 51, 52, 26, 53, 54, 53, 55, 56, 57, 26, + 58, 59, 60, 61, 61, 61, 62, 61, 63, 64, + + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 61, 75, 61, 76, 77, 78, 79, 61, 80, 61, + 61, 81, 82, 84, 85, 84, 85, 88, 92, 88, + 95, 117, 93, 96, 99, 103, 100, 103, 107, 114, + 110, 120, 108, 111, 118, 112, 126, 115, 123, 124, + 128, 101, 93, 116, 127, 121, 132, 130, 141, 170, + 153, 136, 108, 131, 129, 137, 143, 147, 143, 171, + 133, 148, 142, 134, 154, 138, 139, 150, 164, 151, + 155, 159, 152, 165, 156, 207, 172, 160, 176, 208, + 157, 148, 177, 158, 173, 178, 209, 174, 181, 182, + + 179, 184, 88, 180, 88, 103, 92, 103, 185, 186, + 93, 195, 107, 203, 196, 210, 108, 224, 229, 204, + 216, 143, 230, 143, 147, 242, 249, 225, 148, 211, + 93, 243, 217, 244, 245, 252, 108, 257, 258, 266, + 250, 262, 274, 270, 279, 283, 253, 271, 148, 768, + 263, 329, 264, 272, 330, 267, 338, 284, 280, 275, + 339, 343, 375, 769, 376, 407, 414, 344, 429, 377, + 433, 408, 415, 451, 430, 456, 434, 474, 481, 452, + 490, 457, 510, 475, 482, 511, 491, 538, 512, 531, + 431, 513, 532, 539, 534, 533, 586, 535, 557, 476, + + 536, 558, 559, 580, 583, 560, 581, 584, 599, 582, + 585, 604, 628, 648, 671, 770, 587, 605, 629, 649, + 672, 606, 721, 650, 600, 756, 771, 772, 722, 773, + 774, 757, 775, 776, 777, 778, 779, 780, 781, 782, + 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, + 793, 794, 795, 796, 797, 798, 800, 802, 799, 801, + 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, + 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, + 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, + 834, 836, 833, 835, 837, 838, 839, 840, 841, 842, + + 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, + 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, + 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, + 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, + 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, + 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, + 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, + 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, + 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, + 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, + + 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, + 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, + 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, + 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, + 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, + 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, + 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, + 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, + 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, + 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, + + 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, + 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, + 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, + 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, + 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, + 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, + 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, + 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, + 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, + 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, + + 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, + 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, + 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, + 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, + 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1193, 1194, 83, 83, 83, 83, 86, 86, 86, 86, + 89, 89, 89, 89, 91, 91, 94, 91, 104, 104, + 104, 104, 106, 106, 109, 106, 144, 144, 144, 144, + 146, 146, 149, 146, 187, 767, 766, 187, 189, 189, + 765, 189, 764, 763, 762, 761, 760, 759, 758, 755, + + 754, 753, 752, 751, 750, 749, 748, 747, 746, 745, + 744, 743, 742, 741, 740, 739, 738, 737, 736, 735, + 734, 733, 732, 731, 730, 729, 728, 727, 726, 725, + 724, 723, 720, 719, 718, 717, 716, 715, 714, 713, + 712, 711, 710, 709, 708, 707, 706, 705, 704, 703, + 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, + 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, + 682, 681, 680, 679, 678, 677, 676, 675, 674, 673, + 670, 669, 668, 667, 666, 665, 664, 663, 662, 661, + 660, 659, 658, 657, 656, 655, 654, 653, 652, 651, + + 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, + 637, 636, 635, 634, 633, 632, 631, 630, 627, 626, + 625, 624, 623, 622, 621, 620, 619, 618, 617, 616, + 615, 614, 613, 612, 611, 610, 609, 608, 607, 603, + 602, 601, 598, 597, 596, 595, 594, 593, 592, 591, + 590, 589, 588, 579, 578, 577, 576, 575, 574, 573, + 572, 571, 570, 569, 568, 567, 566, 565, 564, 563, + 562, 561, 556, 555, 554, 553, 552, 551, 550, 549, + 548, 547, 546, 545, 544, 543, 542, 541, 540, 537, + 530, 529, 528, 527, 526, 525, 524, 523, 522, 521, + + 520, 519, 518, 517, 516, 515, 514, 509, 508, 507, + 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, + 496, 495, 494, 493, 492, 489, 488, 487, 486, 485, + 484, 483, 480, 479, 478, 477, 473, 472, 471, 470, + 469, 468, 467, 466, 465, 464, 463, 462, 461, 460, + 459, 458, 455, 454, 453, 450, 449, 448, 447, 446, + 445, 444, 443, 442, 441, 440, 439, 438, 437, 436, + 435, 432, 428, 427, 426, 425, 424, 423, 422, 421, + 420, 419, 418, 417, 416, 413, 412, 411, 410, 409, + 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, + + 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, + 386, 385, 384, 383, 382, 381, 380, 379, 378, 374, + 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, + 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, + 353, 352, 351, 350, 349, 348, 347, 346, 345, 342, + 341, 340, 337, 336, 335, 334, 333, 332, 331, 328, + 327, 326, 325, 324, 323, 322, 321, 320, 319, 318, + 317, 316, 315, 314, 313, 312, 311, 310, 309, 308, + 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, + 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, + + 188, 287, 286, 285, 282, 281, 278, 277, 276, 273, + 269, 268, 265, 261, 260, 259, 256, 255, 254, 251, + 248, 247, 246, 241, 240, 239, 145, 238, 237, 236, + 235, 234, 233, 232, 231, 228, 227, 226, 223, 222, + 221, 220, 219, 218, 215, 214, 213, 212, 206, 205, + 202, 201, 200, 199, 105, 198, 197, 194, 193, 192, + 191, 190, 90, 188, 183, 175, 169, 168, 167, 166, + 163, 162, 161, 145, 140, 135, 125, 122, 119, 113, + 105, 102, 98, 97, 90, 1195, 87, 87, 11, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195 }; -static const flex_int16_t yy_chk[1295] = +static const flex_int16_t yy_chk[1331] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 7, 7, 8, 8, 13, 17, 13, 20, 17, 23, - 20, 27, 31, 27, 34, 31, 37, 34, 36, 34, - 39, 41, 41, 43, 23, 44, 36, 45, 17, 37, - 46, 43, 36, 45, 39, 31, 48, 120, 50, 44, - 48, 53, 58, 53, 46, 58, 62, 46, 64, 120, - 48, 48, 50, 61, 64, 61, 72, 63, 61, 67, - 62, 63, 683, 73, 67, 58, 72, 63, 75, 684, - 63, 73, 75, 127, 73, 75, 76, 76, 78, 86, - - 75, 86, 127, 75, 90, 78, 78, 90, 97, 111, - 100, 97, 100, 104, 114, 111, 104, 115, 114, 131, - 140, 144, 140, 131, 144, 114, 150, 90, 151, 151, - 157, 115, 150, 155, 160, 160, 104, 165, 172, 170, - 176, 157, 226, 170, 144, 226, 236, 155, 165, 170, - 236, 240, 685, 686, 176, 172, 271, 240, 271, 301, - 307, 323, 325, 271, 301, 307, 323, 325, 343, 347, - 365, 369, 378, 343, 347, 365, 369, 378, 399, 687, - 400, 399, 323, 400, 418, 466, 419, 418, 421, 419, - 418, 365, 419, 421, 440, 441, 463, 440, 441, 463, - - 464, 477, 463, 464, 481, 466, 464, 505, 688, 481, - 528, 549, 505, 481, 689, 528, 549, 477, 601, 528, - 642, 690, 695, 601, 693, 642, 694, 693, 696, 694, - 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, - 707, 708, 709, 710, 711, 713, 714, 715, 717, 718, - 719, 720, 721, 722, 723, 724, 725, 727, 728, 729, - 727, 728, 730, 731, 732, 733, 734, 735, 736, 737, - 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, - 748, 749, 750, 751, 752, 753, 754, 755, 756, 758, - 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, - - 771, 772, 773, 774, 776, 777, 778, 779, 780, 781, - 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, - 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, - 802, 803, 804, 805, 806, 808, 809, 810, 811, 812, - 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, - 834, 835, 836, 837, 838, 839, 841, 842, 843, 844, - 845, 848, 849, 850, 851, 852, 853, 854, 855, 856, - 857, 858, 859, 861, 862, 865, 866, 867, 868, 869, - 870, 871, 873, 874, 875, 876, 879, 880, 881, 882, - - 883, 884, 885, 886, 887, 888, 889, 890, 893, 894, - 895, 897, 898, 899, 900, 901, 902, 903, 904, 905, - 906, 907, 909, 910, 911, 912, 913, 914, 915, 916, - 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, - 927, 928, 929, 930, 931, 932, 933, 934, 936, 937, - 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, - 948, 950, 951, 952, 953, 954, 955, 956, 957, 958, - 963, 965, 966, 967, 968, 969, 970, 971, 971, 972, - 973, 974, 977, 980, 981, 982, 983, 984, 985, 989, - 991, 992, 993, 994, 995, 996, 997, 998, 1001, 1004, - - 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, - 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, - 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1046, - 1047, 1048, 1052, 1055, 1056, 1057, 1058, 1059, 1060, 1061, - 1062, 1063, 1064, 1065, 1069, 1074, 1075, 1076, 1077, 1078, - 1079, 1080, 1081, 1082, 1083, 1084, 1086, 1087, 1088, 1089, - 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, - 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, - 1110, 1112, 1113, 1114, 1115, 1116, 1117, 1122, 1123, 1124, - - 1125, 1126, 1132, 1133, 1135, 1137, 1139, 1140, 1141, 1142, - 1144, 1148, 1149, 1150, 1153, 1154, 1157, 1162, 1162, 1162, - 1162, 1163, 1163, 1163, 1163, 1164, 1164, 1164, 1164, 1165, - 1165, 1166, 1165, 1167, 1167, 1167, 1167, 1168, 1168, 1169, - 1168, 1170, 1170, 1170, 1170, 1171, 1171, 1172, 1171, 1173, - 682, 681, 1173, 1174, 1174, 680, 1174, 679, 678, 677, - 675, 674, 672, 671, 670, 669, 668, 667, 666, 665, - 664, 663, 660, 659, 658, 657, 656, 655, 654, 653, - 649, 648, 647, 646, 645, 641, 640, 637, 636, 635, - 634, 633, 632, 631, 630, 628, 627, 625, 624, 623, - - 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, - 610, 608, 607, 606, 605, 604, 603, 600, 599, 598, - 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, - 587, 586, 585, 583, 581, 580, 579, 578, 577, 576, - 575, 574, 573, 572, 571, 570, 569, 568, 567, 564, - 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, - 553, 552, 550, 548, 547, 546, 545, 544, 543, 542, - 541, 540, 539, 538, 537, 535, 534, 532, 531, 530, - 529, 527, 526, 525, 524, 523, 522, 520, 519, 517, - 516, 515, 514, 513, 512, 510, 509, 508, 506, 504, - - 503, 502, 501, 500, 499, 498, 497, 494, 493, 492, - 491, 490, 489, 488, 487, 486, 485, 484, 483, 482, - 480, 479, 478, 476, 475, 474, 473, 472, 471, 470, - 469, 468, 467, 461, 460, 459, 458, 457, 452, 451, - 450, 449, 448, 447, 446, 445, 444, 443, 442, 439, - 437, 436, 435, 434, 432, 431, 430, 429, 428, 427, - 426, 425, 424, 423, 422, 420, 417, 416, 415, 414, - 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, - 403, 402, 401, 398, 397, 396, 394, 393, 392, 391, - 390, 389, 388, 387, 386, 385, 384, 383, 382, 381, - - 380, 377, 375, 374, 373, 372, 370, 368, 367, 366, - 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, - 354, 353, 352, 351, 350, 346, 344, 342, 341, 340, - 339, 338, 336, 335, 334, 333, 332, 331, 330, 329, - 328, 327, 326, 324, 322, 321, 320, 319, 318, 317, - 315, 314, 312, 311, 310, 309, 308, 306, 305, 304, - 303, 302, 300, 299, 298, 297, 296, 295, 294, 293, - 292, 291, 290, 289, 288, 287, 286, 284, 283, 281, - 280, 279, 278, 277, 276, 275, 274, 273, 272, 269, - 268, 266, 265, 264, 263, 262, 261, 260, 258, 257, - - 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, - 246, 245, 244, 243, 242, 241, 239, 238, 237, 235, - 233, 232, 231, 230, 228, 227, 225, 224, 223, 222, - 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, - 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, - 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, - 191, 190, 189, 188, 187, 186, 184, 182, 181, 180, - 179, 178, 177, 175, 174, 173, 171, 169, 168, 167, - 166, 164, 163, 162, 159, 158, 156, 154, 153, 152, - 149, 148, 147, 141, 139, 138, 137, 136, 135, 134, - - 133, 132, 130, 129, 128, 126, 125, 124, 123, 122, - 121, 119, 118, 117, 116, 113, 112, 110, 109, 108, - 107, 101, 99, 98, 96, 95, 94, 93, 87, 82, - 77, 74, 71, 70, 69, 68, 66, 65, 55, 49, - 47, 42, 40, 38, 35, 29, 24, 22, 21, 15, - 11, 10, 9, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161 + 5, 5, 5, 7, 7, 8, 8, 13, 17, 13, + 20, 37, 17, 20, 23, 27, 23, 27, 31, 36, + 34, 39, 31, 34, 37, 34, 43, 36, 41, 41, + 44, 23, 17, 36, 43, 39, 46, 45, 50, 74, + 63, 48, 31, 45, 44, 48, 53, 58, 53, 74, + 46, 58, 50, 46, 63, 48, 48, 62, 69, 62, + 64, 65, 62, 69, 64, 117, 75, 65, 77, 117, + 64, 58, 77, 64, 75, 77, 117, 75, 78, 78, + + 77, 80, 88, 77, 88, 103, 92, 103, 80, 80, + 92, 100, 107, 114, 100, 118, 107, 130, 134, 114, + 123, 143, 134, 143, 147, 153, 158, 130, 147, 118, + 92, 153, 123, 154, 154, 160, 107, 164, 164, 171, + 158, 169, 176, 174, 180, 183, 160, 174, 147, 684, + 169, 231, 169, 174, 231, 171, 241, 183, 180, 176, + 241, 245, 279, 685, 279, 311, 317, 245, 333, 279, + 335, 311, 317, 353, 333, 358, 335, 378, 383, 353, + 393, 358, 414, 378, 383, 414, 393, 436, 415, 433, + 333, 415, 433, 436, 434, 433, 484, 434, 456, 378, + + 434, 456, 457, 481, 482, 457, 481, 482, 496, 481, + 482, 500, 524, 547, 570, 686, 484, 500, 524, 547, + 570, 500, 625, 547, 496, 668, 687, 691, 625, 692, + 693, 668, 694, 695, 696, 697, 698, 699, 700, 702, + 703, 705, 706, 707, 708, 709, 710, 711, 712, 713, + 714, 715, 716, 717, 718, 721, 722, 723, 721, 722, + 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, + 734, 735, 736, 737, 738, 739, 741, 742, 743, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 756, + 757, 758, 756, 757, 759, 760, 761, 762, 763, 764, + + 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, + 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, + 785, 786, 788, 791, 792, 793, 794, 795, 796, 797, + 798, 799, 800, 801, 802, 803, 804, 806, 807, 808, + 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, + 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, + 829, 830, 831, 832, 833, 834, 835, 836, 837, 839, + 840, 842, 843, 844, 845, 846, 847, 848, 849, 850, + 851, 852, 853, 854, 856, 857, 858, 859, 860, 861, + 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, + + 873, 874, 875, 876, 877, 880, 881, 882, 883, 884, + 885, 886, 887, 888, 889, 890, 891, 893, 894, 897, + 898, 899, 900, 901, 902, 903, 904, 906, 907, 908, + 909, 912, 913, 914, 915, 916, 917, 918, 919, 920, + 921, 922, 923, 926, 927, 928, 930, 931, 932, 933, + 934, 935, 936, 937, 938, 939, 940, 942, 943, 944, + 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, + 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, + 965, 966, 967, 970, 971, 972, 973, 974, 975, 976, + 977, 978, 979, 980, 981, 982, 984, 985, 986, 987, + + 988, 989, 990, 991, 992, 997, 999, 1000, 1001, 1002, + 1003, 1004, 1005, 1005, 1006, 1007, 1008, 1011, 1014, 1015, + 1016, 1017, 1018, 1019, 1023, 1025, 1026, 1027, 1028, 1029, + 1030, 1031, 1032, 1035, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, + 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, + 1074, 1075, 1076, 1077, 1080, 1081, 1082, 1086, 1089, 1090, + 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1103, + 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, + + 1118, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, + 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, + 1139, 1140, 1141, 1142, 1143, 1144, 1146, 1147, 1148, 1149, + 1150, 1151, 1156, 1157, 1158, 1159, 1160, 1166, 1167, 1169, + 1171, 1173, 1174, 1175, 1176, 1178, 1182, 1183, 1184, 1187, + 1188, 1191, 1196, 1196, 1196, 1196, 1197, 1197, 1197, 1197, + 1198, 1198, 1198, 1198, 1199, 1199, 1200, 1199, 1201, 1201, + 1201, 1201, 1202, 1202, 1203, 1202, 1204, 1204, 1204, 1204, + 1205, 1205, 1206, 1205, 1207, 683, 682, 1207, 1208, 1208, + 681, 1208, 680, 679, 675, 674, 673, 672, 671, 667, + + 666, 665, 662, 661, 660, 659, 658, 656, 655, 654, + 652, 651, 649, 648, 647, 644, 643, 642, 641, 640, + 639, 638, 637, 636, 635, 634, 632, 631, 630, 629, + 628, 627, 624, 623, 622, 621, 620, 619, 618, 617, + 616, 615, 614, 613, 612, 611, 610, 609, 607, 605, + 604, 603, 602, 601, 600, 599, 598, 597, 596, 595, + 594, 593, 592, 591, 590, 587, 586, 585, 584, 583, + 582, 581, 580, 579, 578, 577, 576, 575, 574, 571, + 569, 568, 567, 566, 565, 564, 563, 562, 561, 560, + 559, 558, 557, 555, 554, 553, 551, 550, 549, 548, + + 546, 545, 544, 543, 542, 541, 539, 538, 536, 535, + 534, 533, 532, 531, 529, 528, 527, 525, 523, 522, + 521, 520, 519, 518, 517, 516, 513, 512, 511, 510, + 509, 508, 507, 506, 505, 504, 503, 502, 501, 499, + 498, 497, 495, 494, 493, 492, 491, 490, 489, 488, + 487, 486, 485, 479, 478, 477, 476, 475, 474, 472, + 469, 468, 467, 466, 465, 464, 463, 462, 461, 460, + 459, 458, 455, 454, 452, 451, 450, 449, 447, 446, + 445, 444, 443, 442, 441, 440, 439, 438, 437, 435, + 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, + + 422, 421, 420, 419, 418, 417, 416, 413, 412, 411, + 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, + 399, 398, 397, 396, 395, 392, 390, 389, 388, 387, + 386, 384, 382, 381, 380, 379, 377, 376, 375, 374, + 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, + 363, 361, 357, 355, 354, 352, 351, 350, 349, 348, + 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, + 336, 334, 332, 331, 330, 329, 328, 327, 325, 324, + 322, 321, 320, 319, 318, 316, 315, 314, 313, 312, + 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, + + 300, 299, 298, 297, 296, 294, 293, 292, 290, 289, + 288, 287, 286, 285, 284, 283, 282, 281, 280, 277, + 276, 274, 273, 272, 271, 270, 269, 268, 266, 265, + 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, + 254, 253, 252, 251, 250, 249, 248, 247, 246, 244, + 243, 242, 240, 238, 237, 236, 235, 233, 232, 230, + 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, + 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, + 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, + 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, + + 188, 186, 185, 184, 182, 181, 179, 178, 177, 175, + 173, 172, 170, 168, 167, 166, 163, 162, 161, 159, + 157, 156, 155, 152, 151, 150, 144, 142, 141, 140, + 139, 138, 137, 136, 135, 133, 132, 131, 129, 128, + 127, 126, 125, 124, 122, 121, 120, 119, 116, 115, + 113, 112, 111, 110, 104, 102, 101, 99, 98, 97, + 96, 95, 89, 84, 79, 76, 73, 72, 71, 70, + 68, 67, 66, 55, 49, 47, 42, 40, 38, 35, + 29, 24, 22, 21, 15, 11, 10, 9, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195 }; static yy_state_type yy_last_accepting_state; @@ -1157,8 +1177,10 @@ int pgaf_line_number = 1; static int pgaf_next_brace_is_step = 0; /* - * When the lexer sees "cluster", it sets this flag so the next "{" - * enters CLUSTER_BODY rather than doing the raw block read. + * When the lexer sees "cluster" or "scenario", it sets this flag so the + * next "{" enters CLUSTER_BODY rather than doing the raw block read. + * The CLUSTER_BODY state is reused for "scenario" since the inner syntax + * (formation, node names, ssl, auth) is identical. */ static int pgaf_next_brace_is_cluster = 0; @@ -1190,7 +1212,7 @@ pgaf_strdup(const char *s) char *r = strdup(s); if (!r) { - fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ + fprintf(stderr, "out of memory\n"); exit(1); } return r; @@ -1207,9 +1229,9 @@ pgaf_strdup(const char *s) * call flex's static input() function. */ static void pgaf_read_raw_block(void); -#line 1192 "test_spec_scan.c" +#line 1213 "test_spec_scan.c" -#line 1194 "test_spec_scan.c" +#line 1215 "test_spec_scan.c" #define INITIAL 0 #define CLUSTER_BODY 1 @@ -1336,8 +1358,7 @@ static int input(void); else \ { \ errno = 0; \ - while ((result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && \ - ferror( \ + while ((result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror( \ yyin)) \ { \ if (errno != EINTR) \ @@ -1440,10 +1461,10 @@ YY_DECL } { -#line 89 "test_spec_scan.l" +#line 91 "test_spec_scan.l" -#line 1416 "test_spec_scan.c" +#line 1437 "test_spec_scan.c" while (/*CONSTCOND*/ 1) /* loops until end-of-file is reached */ { @@ -1469,14 +1490,14 @@ YY_DECL while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { yy_current_state = (int) yy_def[yy_current_state]; - if (yy_current_state >= 1162) + if (yy_current_state >= 1196) { yy_c = yy_meta[yy_c]; } } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; - } while (yy_current_state != 1161); + } while (yy_current_state != 1195); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -1491,166 +1512,134 @@ YY_DECL { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ - { *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; - } case 1: - { YY_RULE_SETUP -#line 91 "test_spec_scan.l" +#line 93 "test_spec_scan.l" { /* comment */ } YY_BREAK - } - case 2: - { YY_RULE_SETUP -#line 93 "test_spec_scan.l" +#line 95 "test_spec_scan.l" { pgaf_next_brace_is_cluster = 1; return T_CLUSTER; } YY_BREAK - } - case 3: - { YY_RULE_SETUP -#line 94 "test_spec_scan.l" +#line 96 "test_spec_scan.l" { - return T_MONITOR; + pgaf_next_brace_is_cluster = 1; + return T_SCENARIO; } YY_BREAK - } - case 4: - { YY_RULE_SETUP -#line 95 "test_spec_scan.l" +#line 97 "test_spec_scan.l" { - return T_NODE; + return T_MONITOR; } YY_BREAK - } - case 5: - { YY_RULE_SETUP -#line 96 "test_spec_scan.l" +#line 98 "test_spec_scan.l" { - return T_CITUS_COORDINATOR; + return T_NODE; } YY_BREAK - } - case 6: - { YY_RULE_SETUP -#line 97 "test_spec_scan.l" +#line 99 "test_spec_scan.l" { - return T_CITUS_WORKER; + return T_CITUS_COORDINATOR; } YY_BREAK - } - case 7: - { YY_RULE_SETUP -#line 99 "test_spec_scan.l" +#line 100 "test_spec_scan.l" + { + return T_CITUS_WORKER; + } + + YY_BREAK + case 8: + YY_RULE_SETUP +#line 102 "test_spec_scan.l" { pgaf_next_brace_is_step = 1; return T_SETUP; } YY_BREAK - } - - case 8: - { + case 9: YY_RULE_SETUP -#line 100 "test_spec_scan.l" +#line 103 "test_spec_scan.l" { pgaf_next_brace_is_step = 1; return T_TEARDOWN; } YY_BREAK - } - - case 9: - { + case 10: YY_RULE_SETUP -#line 101 "test_spec_scan.l" +#line 104 "test_spec_scan.l" { pgaf_next_brace_is_step = 1; return T_STEP; } YY_BREAK - } - - case 10: - { + case 11: YY_RULE_SETUP -#line 102 "test_spec_scan.l" +#line 105 "test_spec_scan.l" { return T_SEQUENCE; } YY_BREAK - } - - case 11: - { + case 12: YY_RULE_SETUP -#line 104 "test_spec_scan.l" +#line 107 "test_spec_scan.l" { return T_EQUALS; } YY_BREAK - } - - case 12: - { + case 13: YY_RULE_SETUP -#line 106 "test_spec_scan.l" +#line 109 "test_spec_scan.l" { - yylval.ival = atoi(yytext); /* IGNORE-BANNED */ + yylval.ival = atoi(yytext); return T_INTEGER; } YY_BREAK - } - - case 13: - { + case 14: YY_RULE_SETUP -#line 111 "test_spec_scan.l" +#line 114 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); return T_IDENT; } YY_BREAK - } + case 15: - case 14: - { -/* rule 14 can match eol */ +/* rule 15 can match eol */ YY_RULE_SETUP -#line 116 "test_spec_scan.l" +#line 119 "test_spec_scan.l" { yytext[yyleng - 1] = '\0'; yylval.str = pgaf_strdup(yytext + 1); @@ -1658,12 +1647,9 @@ YY_DECL } YY_BREAK - } - - case 15: - { + case 16: YY_RULE_SETUP -#line 122 "test_spec_scan.l" +#line 125 "test_spec_scan.l" { if (pgaf_next_brace_is_step) { @@ -1680,461 +1666,340 @@ YY_DECL } /* fallback: should not happen in a well-formed file */ - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: unexpected '{' at line %d\n", - pgaf_line_number); + fprintf(stderr, "pgaftest: unexpected '{' at line %d\n", + pgaf_line_number); } YY_BREAK - } + case 17: - case 16: - { -/* rule 16 can match eol */ +/* rule 17 can match eol */ YY_RULE_SETUP -#line 140 "test_spec_scan.l" +#line 143 "test_spec_scan.l" { pgaf_line_number++; } YY_BREAK - } - - case 17: - { + case 18: YY_RULE_SETUP -#line 141 "test_spec_scan.l" +#line 144 "test_spec_scan.l" { /* whitespace */ } YY_BREAK - } - - case 18: - { + case 19: YY_RULE_SETUP -#line 143 "test_spec_scan.l" +#line 146 "test_spec_scan.l" { - fprintf(/* IGNORE-BANNED */ stderr, - "pgaftest: unexpected character '%c' at line %d\n", - yytext[0], pgaf_line_number); + fprintf(stderr, + "pgaftest: unexpected character '%c' at line %d\n", + yytext[0], pgaf_line_number); } YY_BREAK - } - - case 19: - { + case 20: YY_RULE_SETUP -#line 148 "test_spec_scan.l" +#line 151 "test_spec_scan.l" { /* comment */ } YY_BREAK - } + case 21: - case 20: - { -/* rule 20 can match eol */ +/* rule 21 can match eol */ YY_RULE_SETUP -#line 149 "test_spec_scan.l" +#line 152 "test_spec_scan.l" { pgaf_line_number++; } YY_BREAK - } - - case 21: - { + case 22: YY_RULE_SETUP -#line 150 "test_spec_scan.l" +#line 153 "test_spec_scan.l" { /* whitespace */ } YY_BREAK - } - - case 22: - { + case 23: YY_RULE_SETUP -#line 152 "test_spec_scan.l" +#line 155 "test_spec_scan.l" { return T_MONITOR; } YY_BREAK - } - - case 23: - { + case 24: YY_RULE_SETUP -#line 153 "test_spec_scan.l" +#line 156 "test_spec_scan.l" { return T_IMAGE_TARGET; } YY_BREAK - } - - case 24: - { + case 25: YY_RULE_SETUP -#line 154 "test_spec_scan.l" +#line 157 "test_spec_scan.l" { return T_IMAGE; } YY_BREAK - } - - case 25: - { + case 26: YY_RULE_SETUP -#line 155 "test_spec_scan.l" +#line 158 "test_spec_scan.l" { return T_SSL; } YY_BREAK - } - - case 26: - { + case 27: YY_RULE_SETUP -#line 156 "test_spec_scan.l" +#line 159 "test_spec_scan.l" { return T_AUTH_METHOD; } YY_BREAK - } - - case 27: - { + case 28: YY_RULE_SETUP -#line 157 "test_spec_scan.l" +#line 160 "test_spec_scan.l" { return T_AUTH; } YY_BREAK - } - - case 28: - { + case 29: YY_RULE_SETUP -#line 158 "test_spec_scan.l" +#line 161 "test_spec_scan.l" { return T_FORMATION; } YY_BREAK - } - - case 29: - { + case 30: YY_RULE_SETUP -#line 159 "test_spec_scan.l" +#line 162 "test_spec_scan.l" { return T_NUM_SYNC; } YY_BREAK - } - - case 30: - { + case 31: YY_RULE_SETUP -#line 160 "test_spec_scan.l" +#line 163 "test_spec_scan.l" { return T_NODE; } YY_BREAK - } - - case 31: - { + case 32: YY_RULE_SETUP -#line 162 "test_spec_scan.l" +#line 165 "test_spec_scan.l" { return T_COORDINATOR; } YY_BREAK - } - - case 32: - { + case 33: YY_RULE_SETUP -#line 163 "test_spec_scan.l" +#line 166 "test_spec_scan.l" { return T_WORKER; } YY_BREAK - } - - case 33: - { + case 34: YY_RULE_SETUP -#line 164 "test_spec_scan.l" +#line 167 "test_spec_scan.l" { return T_ASYNC; } YY_BREAK - } - - case 34: - { + case 35: YY_RULE_SETUP -#line 165 "test_spec_scan.l" +#line 168 "test_spec_scan.l" { return T_NO_MONITOR; } YY_BREAK - } - - case 35: - { + case 36: YY_RULE_SETUP -#line 166 "test_spec_scan.l" +#line 169 "test_spec_scan.l" { return T_PASSWORD; } YY_BREAK - } - - case 36: - { + case 37: YY_RULE_SETUP -#line 167 "test_spec_scan.l" +#line 170 "test_spec_scan.l" { return T_MONITOR_PASSWORD; } YY_BREAK - } - - case 37: - { + case 38: YY_RULE_SETUP -#line 168 "test_spec_scan.l" +#line 171 "test_spec_scan.l" { return T_LAUNCH; } YY_BREAK - } - - case 38: - { + case 39: YY_RULE_SETUP -#line 169 "test_spec_scan.l" +#line 172 "test_spec_scan.l" { return T_DEFERRED; } YY_BREAK - } - - case 39: - { + case 40: YY_RULE_SETUP -#line 170 "test_spec_scan.l" +#line 173 "test_spec_scan.l" { return T_IMMEDIATE; } YY_BREAK - } - - case 40: - { + case 41: YY_RULE_SETUP -#line 171 "test_spec_scan.l" +#line 174 "test_spec_scan.l" { return T_INITIALLY; } YY_BREAK - } - - case 41: - { + case 42: YY_RULE_SETUP -#line 172 "test_spec_scan.l" +#line 175 "test_spec_scan.l" { return T_STOPPED; } YY_BREAK - } - - case 42: - { + case 43: YY_RULE_SETUP -#line 173 "test_spec_scan.l" +#line 176 "test_spec_scan.l" { return T_VOLUME; } YY_BREAK - } - - case 43: - { + case 44: YY_RULE_SETUP -#line 174 "test_spec_scan.l" +#line 177 "test_spec_scan.l" { return T_LISTEN; } YY_BREAK - } - - case 44: - { + case 45: YY_RULE_SETUP -#line 175 "test_spec_scan.l" +#line 178 "test_spec_scan.l" { return T_CITUS_SECONDARY; } YY_BREAK - } - - case 45: - { + case 46: YY_RULE_SETUP -#line 176 "test_spec_scan.l" +#line 179 "test_spec_scan.l" { return T_CANDIDATE_PRIORITY; } YY_BREAK - } - - case 46: - { + case 47: YY_RULE_SETUP -#line 177 "test_spec_scan.l" +#line 180 "test_spec_scan.l" { return T_GROUP; } YY_BREAK - } - - case 47: - { + case 48: YY_RULE_SETUP -#line 178 "test_spec_scan.l" +#line 181 "test_spec_scan.l" { return T_PORT; } YY_BREAK - } - - case 48: - { + case 49: YY_RULE_SETUP -#line 179 "test_spec_scan.l" +#line 182 "test_spec_scan.l" { return T_CITUS_CLUSTER_NAME; } YY_BREAK - } - - case 49: - { + case 50: YY_RULE_SETUP -#line 180 "test_spec_scan.l" +#line 183 "test_spec_scan.l" { return T_DEBIAN_CLUSTER; } YY_BREAK - } - - case 50: - { + case 51: YY_RULE_SETUP -#line 181 "test_spec_scan.l" +#line 184 "test_spec_scan.l" { return T_REPLICATION_QUORUM; } YY_BREAK - } - - case 51: - { + case 52: YY_RULE_SETUP -#line 182 "test_spec_scan.l" +#line 185 "test_spec_scan.l" { return T_REPLICATION_PASSWORD; } YY_BREAK - } - - case 52: - { + case 53: YY_RULE_SETUP -#line 183 "test_spec_scan.l" +#line 186 "test_spec_scan.l" { return T_EXTENSION_VERSION; } YY_BREAK - } - - case 53: - { + case 54: YY_RULE_SETUP -#line 184 "test_spec_scan.l" +#line 187 "test_spec_scan.l" { return T_BIND_SOURCE; } YY_BREAK - } - - case 54: - { + case 55: YY_RULE_SETUP -#line 186 "test_spec_scan.l" +#line 189 "test_spec_scan.l" { return T_EQUALS; } YY_BREAK - } - - case 55: - { + case 56: YY_RULE_SETUP -#line 188 "test_spec_scan.l" +#line 191 "test_spec_scan.l" { - yylval.ival = atoi(yytext); /* IGNORE-BANNED */ + yylval.ival = atoi(yytext); return T_INTEGER; } YY_BREAK - } + case 57: - case 56: - { -/* rule 56 can match eol */ +/* rule 57 can match eol */ YY_RULE_SETUP -#line 193 "test_spec_scan.l" +#line 196 "test_spec_scan.l" { yytext[yyleng - 1] = '\0'; yylval.str = pgaf_strdup(yytext + 1); @@ -2142,24 +2007,18 @@ YY_DECL } YY_BREAK - } - - case 57: - { + case 58: YY_RULE_SETUP -#line 199 "test_spec_scan.l" +#line 202 "test_spec_scan.l" { pgaf_cluster_depth++; return T_LBRACE; } YY_BREAK - } - - case 58: - { + case 59: YY_RULE_SETUP -#line 204 "test_spec_scan.l" +#line 207 "test_spec_scan.l" { pgaf_cluster_depth--; if (pgaf_cluster_depth == 0) @@ -2170,887 +2029,697 @@ YY_DECL } YY_BREAK - } - - case 59: - { - YY_RULE_SETUP -#line 211 "test_spec_scan.l" - { - return T_FS_INIT; - } - - YY_BREAK - } - case 60: - { YY_RULE_SETUP -#line 212 "test_spec_scan.l" +#line 214 "test_spec_scan.l" { - return T_FS_SINGLE; + return T_FS_INIT; } YY_BREAK - } - case 61: - { YY_RULE_SETUP -#line 213 "test_spec_scan.l" +#line 215 "test_spec_scan.l" { - return T_FS_PRIMARY; + return T_FS_SINGLE; } YY_BREAK - } - case 62: - { YY_RULE_SETUP -#line 214 "test_spec_scan.l" +#line 216 "test_spec_scan.l" { - return T_FS_WAIT_PRIMARY; + return T_FS_PRIMARY; } YY_BREAK - } - case 63: - { YY_RULE_SETUP -#line 215 "test_spec_scan.l" +#line 217 "test_spec_scan.l" { return T_FS_WAIT_PRIMARY; } YY_BREAK - } - case 64: - { YY_RULE_SETUP -#line 216 "test_spec_scan.l" +#line 218 "test_spec_scan.l" { - return T_FS_WAIT_STANDBY; + return T_FS_WAIT_PRIMARY; } YY_BREAK - } - case 65: - { YY_RULE_SETUP -#line 217 "test_spec_scan.l" +#line 219 "test_spec_scan.l" { return T_FS_WAIT_STANDBY; } YY_BREAK - } - case 66: - { YY_RULE_SETUP -#line 218 "test_spec_scan.l" +#line 220 "test_spec_scan.l" { - return T_FS_DEMOTED; + return T_FS_WAIT_STANDBY; } YY_BREAK - } - case 67: - { YY_RULE_SETUP -#line 219 "test_spec_scan.l" +#line 221 "test_spec_scan.l" { - return T_FS_DEMOTE_TIMEOUT; + return T_FS_DEMOTED; } YY_BREAK - } - case 68: - { YY_RULE_SETUP -#line 220 "test_spec_scan.l" +#line 222 "test_spec_scan.l" { return T_FS_DEMOTE_TIMEOUT; } YY_BREAK - } - case 69: - { YY_RULE_SETUP -#line 221 "test_spec_scan.l" +#line 223 "test_spec_scan.l" { - return T_FS_DRAINING; + return T_FS_DEMOTE_TIMEOUT; } YY_BREAK - } - case 70: - { YY_RULE_SETUP -#line 222 "test_spec_scan.l" +#line 224 "test_spec_scan.l" { - return T_FS_SECONDARY; + return T_FS_DRAINING; } YY_BREAK - } - case 71: - { YY_RULE_SETUP -#line 223 "test_spec_scan.l" +#line 225 "test_spec_scan.l" { - return T_FS_CATCHINGUP; + return T_FS_SECONDARY; } YY_BREAK - } - case 72: - { YY_RULE_SETUP -#line 224 "test_spec_scan.l" +#line 226 "test_spec_scan.l" { - return T_FS_PREP_PROMOTION; + return T_FS_CATCHINGUP; } YY_BREAK - } - case 73: - { YY_RULE_SETUP -#line 225 "test_spec_scan.l" +#line 227 "test_spec_scan.l" { return T_FS_PREP_PROMOTION; } YY_BREAK - } - case 74: - { YY_RULE_SETUP -#line 226 "test_spec_scan.l" +#line 228 "test_spec_scan.l" { - return T_FS_STOP_REPLICATION; + return T_FS_PREP_PROMOTION; } YY_BREAK - } - case 75: - { YY_RULE_SETUP -#line 227 "test_spec_scan.l" +#line 229 "test_spec_scan.l" { return T_FS_STOP_REPLICATION; } YY_BREAK - } - case 76: - { YY_RULE_SETUP -#line 228 "test_spec_scan.l" +#line 230 "test_spec_scan.l" { - return T_FS_MAINTENANCE; + return T_FS_STOP_REPLICATION; } YY_BREAK - } - case 77: - { YY_RULE_SETUP -#line 229 "test_spec_scan.l" +#line 231 "test_spec_scan.l" { - return T_FS_JOIN_PRIMARY; + return T_FS_MAINTENANCE; } YY_BREAK - } - case 78: - { YY_RULE_SETUP -#line 230 "test_spec_scan.l" +#line 232 "test_spec_scan.l" { return T_FS_JOIN_PRIMARY; } YY_BREAK - } - case 79: - { YY_RULE_SETUP -#line 231 "test_spec_scan.l" +#line 233 "test_spec_scan.l" { - return T_FS_APPLY_SETTINGS; + return T_FS_JOIN_PRIMARY; } YY_BREAK - } - case 80: - { YY_RULE_SETUP -#line 232 "test_spec_scan.l" +#line 234 "test_spec_scan.l" { return T_FS_APPLY_SETTINGS; } YY_BREAK - } - case 81: - { YY_RULE_SETUP -#line 233 "test_spec_scan.l" +#line 235 "test_spec_scan.l" { - return T_FS_PREPARE_MAINTENANCE; + return T_FS_APPLY_SETTINGS; } YY_BREAK - } - case 82: - { YY_RULE_SETUP -#line 234 "test_spec_scan.l" +#line 236 "test_spec_scan.l" { return T_FS_PREPARE_MAINTENANCE; } YY_BREAK - } - case 83: - { YY_RULE_SETUP -#line 235 "test_spec_scan.l" +#line 237 "test_spec_scan.l" { - return T_FS_WAIT_MAINTENANCE; + return T_FS_PREPARE_MAINTENANCE; } YY_BREAK - } - case 84: - { YY_RULE_SETUP -#line 236 "test_spec_scan.l" +#line 238 "test_spec_scan.l" { return T_FS_WAIT_MAINTENANCE; } YY_BREAK - } - case 85: - { YY_RULE_SETUP -#line 237 "test_spec_scan.l" +#line 239 "test_spec_scan.l" { - return T_FS_REPORT_LSN; + return T_FS_WAIT_MAINTENANCE; } YY_BREAK - } - case 86: - { YY_RULE_SETUP -#line 238 "test_spec_scan.l" +#line 240 "test_spec_scan.l" { return T_FS_REPORT_LSN; } YY_BREAK - } - case 87: - { YY_RULE_SETUP -#line 239 "test_spec_scan.l" +#line 241 "test_spec_scan.l" { - return T_FS_FAST_FORWARD; + return T_FS_REPORT_LSN; } YY_BREAK - } - case 88: - { YY_RULE_SETUP -#line 240 "test_spec_scan.l" +#line 242 "test_spec_scan.l" { return T_FS_FAST_FORWARD; } YY_BREAK - } - case 89: - { YY_RULE_SETUP -#line 241 "test_spec_scan.l" +#line 243 "test_spec_scan.l" { - return T_FS_JOIN_SECONDARY; + return T_FS_FAST_FORWARD; } YY_BREAK - } - case 90: - { YY_RULE_SETUP -#line 242 "test_spec_scan.l" +#line 244 "test_spec_scan.l" { return T_FS_JOIN_SECONDARY; } YY_BREAK - } - case 91: - { YY_RULE_SETUP -#line 243 "test_spec_scan.l" +#line 245 "test_spec_scan.l" { - return T_FS_DROPPED; + return T_FS_JOIN_SECONDARY; } YY_BREAK - } - case 92: - { YY_RULE_SETUP -#line 245 "test_spec_scan.l" +#line 246 "test_spec_scan.l" + { + return T_FS_DROPPED; + } + + YY_BREAK + case 93: + YY_RULE_SETUP +#line 248 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); return T_IDENT; } YY_BREAK - } - - case 93: - { + case 94: YY_RULE_SETUP -#line 250 "test_spec_scan.l" +#line 253 "test_spec_scan.l" { /* comment */ } YY_BREAK - } + case 95: - case 94: - { -/* rule 94 can match eol */ +/* rule 95 can match eol */ YY_RULE_SETUP -#line 251 "test_spec_scan.l" +#line 254 "test_spec_scan.l" { pgaf_line_number++; } YY_BREAK - } - - case 95: - { + case 96: YY_RULE_SETUP -#line 252 "test_spec_scan.l" +#line 255 "test_spec_scan.l" { /* whitespace */ } YY_BREAK - } - - case 96: - { + case 97: YY_RULE_SETUP -#line 254 "test_spec_scan.l" +#line 257 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_EXEC_FAILS; } YY_BREAK - } - - case 97: - { + case 98: YY_RULE_SETUP -#line 255 "test_spec_scan.l" +#line 258 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_EXEC; } YY_BREAK - } - - case 98: - { + case 99: YY_RULE_SETUP -#line 256 "test_spec_scan.l" +#line 259 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_PG_AUTOCTL; } YY_BREAK - } - - case 99: - { + case 100: YY_RULE_SETUP -#line 258 "test_spec_scan.l" +#line 261 "test_spec_scan.l" { return T_WAIT; } YY_BREAK - } - - case 100: - { + case 101: YY_RULE_SETUP -#line 259 "test_spec_scan.l" +#line 262 "test_spec_scan.l" { return T_UNTIL; } YY_BREAK - } - - case 101: - { + case 102: YY_RULE_SETUP -#line 260 "test_spec_scan.l" +#line 263 "test_spec_scan.l" { return T_TIMEOUT; } YY_BREAK - } - - case 102: - { + case 103: YY_RULE_SETUP -#line 261 "test_spec_scan.l" +#line 264 "test_spec_scan.l" { return T_ASSERT; } YY_BREAK - } - - case 103: - { + case 104: YY_RULE_SETUP -#line 262 "test_spec_scan.l" +#line 265 "test_spec_scan.l" { return T_SQL; } YY_BREAK - } - - case 104: - { + case 105: YY_RULE_SETUP -#line 263 "test_spec_scan.l" +#line 266 "test_spec_scan.l" { return T_EXPECT; } YY_BREAK - } - - case 105: - { + case 106: YY_RULE_SETUP -#line 264 "test_spec_scan.l" +#line 267 "test_spec_scan.l" { return T_ERROR; } YY_BREAK - } - - case 106: - { + case 107: YY_RULE_SETUP -#line 265 "test_spec_scan.l" +#line 268 "test_spec_scan.l" { return T_PROMOTE; } YY_BREAK - } - - case 107: - { + case 108: YY_RULE_SETUP -#line 266 "test_spec_scan.l" +#line 269 "test_spec_scan.l" { return T_NETWORK; } YY_BREAK - } - - case 108: - { + case 109: YY_RULE_SETUP -#line 267 "test_spec_scan.l" +#line 270 "test_spec_scan.l" { return T_DISCONNECT; } YY_BREAK - } - - case 109: - { + case 110: YY_RULE_SETUP -#line 268 "test_spec_scan.l" +#line 271 "test_spec_scan.l" { return T_CONNECT; } YY_BREAK - } - - case 110: - { + case 111: YY_RULE_SETUP -#line 269 "test_spec_scan.l" +#line 272 "test_spec_scan.l" { return T_SLEEP; } YY_BREAK - } - - case 111: - { + case 112: YY_RULE_SETUP -#line 270 "test_spec_scan.l" +#line 273 "test_spec_scan.l" { return T_COMPOSE; } YY_BREAK - } - - case 112: - { + case 113: YY_RULE_SETUP -#line 271 "test_spec_scan.l" +#line 274 "test_spec_scan.l" { return T_DOWN; } YY_BREAK - } - - case 113: - { + case 114: YY_RULE_SETUP -#line 272 "test_spec_scan.l" +#line 275 "test_spec_scan.l" { return T_START; } YY_BREAK - } - - case 114: - { + case 115: YY_RULE_SETUP -#line 273 "test_spec_scan.l" +#line 276 "test_spec_scan.l" { return T_STOP; } YY_BREAK - } - - case 115: - { + case 116: YY_RULE_SETUP -#line 274 "test_spec_scan.l" +#line 277 "test_spec_scan.l" { return T_STOPPED; } YY_BREAK - } - - case 116: - { + case 117: YY_RULE_SETUP -#line 275 "test_spec_scan.l" +#line 278 "test_spec_scan.l" { return T_KILL; } YY_BREAK - } - - case 117: - { + case 118: YY_RULE_SETUP -#line 276 "test_spec_scan.l" +#line 279 "test_spec_scan.l" { return T_IN; } YY_BREAK - } - - case 118: - { + case 119: YY_RULE_SETUP -#line 277 "test_spec_scan.l" +#line 280 "test_spec_scan.l" { return T_STATE; } YY_BREAK - } - - case 119: - { + case 120: YY_RULE_SETUP -#line 278 "test_spec_scan.l" +#line 281 "test_spec_scan.l" { return T_ASSIGNED_STATE; } YY_BREAK - } - - case 120: - { + case 121: YY_RULE_SETUP -#line 279 "test_spec_scan.l" +#line 282 "test_spec_scan.l" { return T_CANDIDATE_PRIORITY; } YY_BREAK - } - - case 121: - { + case 122: YY_RULE_SETUP -#line 280 "test_spec_scan.l" +#line 283 "test_spec_scan.l" { return T_GROUP; } YY_BREAK - } - - case 122: - { + case 123: YY_RULE_SETUP -#line 281 "test_spec_scan.l" +#line 284 "test_spec_scan.l" { return T_AND; } YY_BREAK - } - - case 123: - { + case 124: YY_RULE_SETUP -#line 282 "test_spec_scan.l" +#line 285 "test_spec_scan.l" { return T_IS; } YY_BREAK - } - - case 124: - { + case 125: YY_RULE_SETUP -#line 283 "test_spec_scan.l" +#line 286 "test_spec_scan.l" { return T_WITH; } YY_BREAK - } - - case 125: - { + case 126: YY_RULE_SETUP -#line 284 "test_spec_scan.l" +#line 287 "test_spec_scan.l" { return T_EQUALS; } YY_BREAK - } - - case 126: - { + case 127: YY_RULE_SETUP -#line 285 "test_spec_scan.l" +#line 288 "test_spec_scan.l" { return T_COMMA; } YY_BREAK - } - - case 127: - { + case 128: YY_RULE_SETUP -#line 286 "test_spec_scan.l" +#line 289 "test_spec_scan.l" { return T_POSTGRES; } YY_BREAK - } - - case 128: - { + case 129: YY_RULE_SETUP -#line 287 "test_spec_scan.l" +#line 290 "test_spec_scan.l" { return T_STAYS; } YY_BREAK - } - - case 129: - { + case 130: YY_RULE_SETUP -#line 288 "test_spec_scan.l" +#line 291 "test_spec_scan.l" { return T_WHILE; } YY_BREAK - } - - case 130: - { + case 131: YY_RULE_SETUP -#line 289 "test_spec_scan.l" +#line 292 "test_spec_scan.l" { return T_THROUGH; } YY_BREAK - } - - case 131: - { + case 132: YY_RULE_SETUP -#line 290 "test_spec_scan.l" +#line 293 "test_spec_scan.l" { return T_SET; } YY_BREAK - } - - case 132: - { + case 133: YY_RULE_SETUP -#line 291 "test_spec_scan.l" +#line 294 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_INJECT; } YY_BREAK - } - - case 133: - { + case 134: YY_RULE_SETUP -#line 292 "test_spec_scan.l" +#line 295 "test_spec_scan.l" { return T_LOGS; } YY_BREAK - } - - case 134: - { + case 135: YY_RULE_SETUP -#line 293 "test_spec_scan.l" +#line 296 "test_spec_scan.l" { return T_NOT; } YY_BREAK - } - - case 135: - { + case 136: YY_RULE_SETUP -#line 294 "test_spec_scan.l" +#line 297 "test_spec_scan.l" { return T_CONTAINS; } YY_BREAK - } - - case 136: - { + case 137: YY_RULE_SETUP -#line 295 "test_spec_scan.l" +#line 298 "test_spec_scan.l" { return T_MATCHES; } YY_BREAK - } + case 138: + YY_RULE_SETUP +#line 299 "test_spec_scan.l" + { + return T_NODE_ACTIVE; + } - case 137: - { + YY_BREAK + case 139: YY_RULE_SETUP -#line 297 "test_spec_scan.l" +#line 300 "test_spec_scan.l" { - yylval.ival = atoi(yytext); /* IGNORE-BANNED */ - return T_INTEGER; + return T_MARK; } YY_BREAK - } + case 140: + YY_RULE_SETUP +#line 301 "test_spec_scan.l" + { + return T_HEALTHY; + } - case 138: - { -/* rule 138 can match eol */ + YY_BREAK + case 141: YY_RULE_SETUP #line 302 "test_spec_scan.l" + { + return T_UNHEALTHY; + } + + YY_BREAK + case 142: + YY_RULE_SETUP +#line 303 "test_spec_scan.l" + { + return T_STATES; + } + + YY_BREAK + case 143: + YY_RULE_SETUP +#line 304 "test_spec_scan.l" + { + return ':'; + } + + YY_BREAK + case 144: + YY_RULE_SETUP +#line 306 "test_spec_scan.l" + { + yylval.ival = atoi(yytext); + return T_INTEGER; + } + + YY_BREAK + case 145: + +/* rule 145 can match eol */ + YY_RULE_SETUP +#line 311 "test_spec_scan.l" { yytext[yyleng - 1] = '\0'; yylval.str = pgaf_strdup(yytext + 1); @@ -3058,12 +2727,9 @@ YY_DECL } YY_BREAK - } - - case 139: - { + case 146: YY_RULE_SETUP -#line 308 "test_spec_scan.l" +#line 317 "test_spec_scan.l" { if (pgaf_next_brace_is_while) { @@ -3076,12 +2742,9 @@ YY_DECL } YY_BREAK - } - - case 140: - { + case 147: YY_RULE_SETUP -#line 318 "test_spec_scan.l" +#line 327 "test_spec_scan.l" { if (pgaf_step_brace_depth > 0) { @@ -3094,34 +2757,25 @@ YY_DECL } YY_BREAK - } - - case 141: - { + case 148: YY_RULE_SETUP -#line 328 "test_spec_scan.l" +#line 337 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); return T_IDENT; } YY_BREAK - } - - case 142: - { + case 149: YY_RULE_SETUP -#line 333 "test_spec_scan.l" +#line 342 "test_spec_scan.l" { /* skip whitespace before service name */ } YY_BREAK - } - - case 143: - { + case 150: YY_RULE_SETUP -#line 335 "test_spec_scan.l" +#line 344 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); BEGIN(EXEC_ARGS_REST); @@ -3129,25 +2783,20 @@ YY_DECL } YY_BREAK - } + case 151: - case 144: - { -/* rule 144 can match eol */ +/* rule 151 can match eol */ YY_RULE_SETUP -#line 341 "test_spec_scan.l" +#line 350 "test_spec_scan.l" { pgaf_line_number++; BEGIN(STEP_BODY); } YY_BREAK - } - - case 145: - { + case 152: YY_RULE_SETUP -#line 346 "test_spec_scan.l" +#line 355 "test_spec_scan.l" { char *p = yytext; while (*p == ' ' || *p == '\t') @@ -3160,39 +2809,30 @@ YY_DECL } YY_BREAK - } + case 153: - case 146: - { -/* rule 146 can match eol */ +/* rule 153 can match eol */ YY_RULE_SETUP -#line 354 "test_spec_scan.l" +#line 363 "test_spec_scan.l" { pgaf_line_number++; BEGIN(STEP_BODY); } YY_BREAK - } - - case 147: - { + case 154: YY_RULE_SETUP -#line 359 "test_spec_scan.l" +#line 368 "test_spec_scan.l" ECHO; YY_BREAK - } - -#line 2301 "test_spec_scan.c" +#line 2357 "test_spec_scan.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CLUSTER_BODY): case YY_STATE_EOF(STEP_BODY): case YY_STATE_EOF(EXEC_ARGS): case YY_STATE_EOF(EXEC_ARGS_REST): - { yyterminate(); - } case YY_END_OF_BUFFER: { @@ -3226,8 +2866,8 @@ YY_DECL * end-of-buffer state). Contrast this with the test * in input(). */ - if ((yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] - ) + if ((yy_c_buf_p) <= + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]) { /* This was really a NUL. */ yy_state_type yy_next_state; @@ -3297,7 +2937,6 @@ YY_DECL } case EOB_ACT_CONTINUE_SCAN: - { (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; @@ -3306,10 +2945,8 @@ YY_DECL yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; - } case EOB_ACT_LAST_MATCH: - { (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; @@ -3318,17 +2955,14 @@ YY_DECL yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; - } } } break; } default: - { YY_FATAL_ERROR( "fatal flex scanner internal error--no action found"); - } } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ @@ -3517,7 +3151,7 @@ yy_get_previous_state(void) while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { yy_current_state = (int) yy_def[yy_current_state]; - if (yy_current_state >= 1162) + if (yy_current_state >= 1196) { yy_c = yy_meta[yy_c]; } @@ -3549,13 +3183,13 @@ yy_try_NUL_trans(yy_state_type yy_current_state) while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { yy_current_state = (int) yy_def[yy_current_state]; - if (yy_current_state >= 1162) + if (yy_current_state >= 1196) { yy_c = yy_meta[yy_c]; } } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 1161); + yy_is_jam = (yy_current_state == 1195); return yy_is_jam ? 0 : yy_current_state; } @@ -3597,7 +3231,7 @@ input(void) switch (yy_get_next_buffer()) { case EOB_ACT_LAST_MATCH: - { + /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to @@ -3610,7 +3244,6 @@ input(void) /* Reset buffer status. */ yyrestart(yyin); - } /*FALLTHROUGH*/ @@ -3633,10 +3266,8 @@ input(void) } case EOB_ACT_CONTINUE_SCAN: - { (yy_c_buf_p) = (yytext_ptr) + offset; break; - } } } } @@ -4071,7 +3702,7 @@ yy_scan_bytes(const char *yybytes, yy_size_t _yybytes_len) static void yynoreturn yy_fatal_error(const char *msg) { - fprintf(stderr, "%s\n", msg); /* IGNORE-BANNED */ + fprintf(stderr, "%s\n", msg); exit(YY_EXIT_FAILURE); } @@ -4306,7 +3937,7 @@ yyfree(void *ptr) #define YYTABLES_NAME "yytables" -#line 359 "test_spec_scan.l" +#line 368 "test_spec_scan.l" static void diff --git a/src/bin/pgaftest/test_spec_scan.l b/src/bin/pgaftest/test_spec_scan.l index f2f3beb23..4a1352131 100644 --- a/src/bin/pgaftest/test_spec_scan.l +++ b/src/bin/pgaftest/test_spec_scan.l @@ -31,8 +31,10 @@ int pgaf_line_number = 1; static int pgaf_next_brace_is_step = 0; /* - * When the lexer sees "cluster", it sets this flag so the next "{" - * enters CLUSTER_BODY rather than doing the raw block read. + * When the lexer sees "cluster" or "scenario", it sets this flag so the + * next "{" enters CLUSTER_BODY rather than doing the raw block read. + * The CLUSTER_BODY state is reused for "scenario" since the inner syntax + * (formation, node names, ssl, auth) is identical. */ static int pgaf_next_brace_is_cluster = 0; @@ -91,6 +93,7 @@ static void pgaf_read_raw_block(void); "#"[^\n]* { /* comment */ } "cluster" { pgaf_next_brace_is_cluster = 1; return T_CLUSTER; } +"scenario" { pgaf_next_brace_is_cluster = 1; return T_SCENARIO; } "monitor" { return T_MONITOR; } "node" { return T_NODE; } "citus-coordinator" { return T_CITUS_COORDINATOR; } @@ -297,6 +300,7 @@ static void pgaf_read_raw_block(void); "mark" { return T_MARK; } "healthy" { return T_HEALTHY; } "unhealthy" { return T_UNHEALTHY; } +"states" { return T_STATES; } ":" { return ':'; } [0-9]+[sS]? { diff --git a/src/monitor/node_active_protocol.c b/src/monitor/node_active_protocol.c index 03eafa2b4..f1731f15e 100644 --- a/src/monitor/node_active_protocol.c +++ b/src/monitor/node_active_protocol.c @@ -26,6 +26,7 @@ #include "access/htup_details.h" #include "access/xlogdefs.h" +#include "utils/timestamp.h" #include "catalog/pg_enum.h" #include "nodes/makefuncs.h" #include "nodes/parsenodes.h" @@ -484,6 +485,17 @@ NodeActive(char *formationId, AutoFailoverNodeState *currentNodeState) currentNodeState->pgsrSyncState, currentNodeState->reportedTLI, currentNodeState->reportedLSN); + + /* + * Sync the in-memory struct with the values just written to the DB. + * ReportAutoFailoverNodeState updates reportedpgisrunning, reportedtli, + * and reporttime in the DB, but not in this struct. ProceedGroupState + * relies on NodeIsHealthy() which reads pgIsRunning and reportTime from + * the struct, so leaving them stale causes spurious health failures. + */ + pgAutoFailoverNode->pgIsRunning = currentNodeState->pgIsRunning; + pgAutoFailoverNode->reportedTLI = currentNodeState->reportedTLI; + pgAutoFailoverNode->reportTime = GetCurrentTimestamp(); } LockNodeGroup(formationId, currentNodeState->groupId, ExclusiveLock); diff --git a/src/monitor/node_metadata.c b/src/monitor/node_metadata.c index fb6bcf18b..574e9fc52 100644 --- a/src/monitor/node_metadata.c +++ b/src/monitor/node_metadata.c @@ -2060,6 +2060,15 @@ NodeIsHealthy(const AutoFailoverNode *node, const struct GroupStateContext *ctx) return node->pgIsRunning; } + /* + * UNKNOWN (-1) means no health-check worker has run yet. Trust the + * keeper's own pgIsRunning report; we have no contradictory evidence. + */ + if (node->health == NODE_HEALTH_UNKNOWN) + { + return node->pgIsRunning; + } + return node->health == NODE_HEALTH_GOOD && node->pgIsRunning; } diff --git a/tests/tap/specs/monitor_fsm_health.pgaf b/tests/tap/specs/monitor_fsm_health.pgaf new file mode 100644 index 000000000..4c04f1c1b --- /dev/null +++ b/tests/tap/specs/monitor_fsm_health.pgaf @@ -0,0 +1,198 @@ +# Monitor FSM health-predicate regression tests. +# +# Covers the behaviour exposed by issues #1062 and #1032. +# +# Background +# ---------- +# The original IsHealthy() function had an inverted condition in its +# "recent-report overrides bad health-check" clause: +# +# TimestampDifferenceExceeds(reportTime, now, 1s) /* now − reportTime > 1 s */ +# +# Because reportTime is set inside the same node_active() call and ctx->now is +# captured microseconds later, now − reportTime is always ~0 ms — the clause +# never fired. The predicate therefore reduced to: +# +# health == GOOD && pgIsRunning +# +# NodeIsHealthy() in this branch uses the corrected form: +# +# !TimestampDifferenceExceeds(reportTime, ctx->now, 1s) /* < 1 s */ +# +# which fires for the current reporter, matching the comment's stated intent. +# +# The fix matters in two concrete scenarios: +# +# #1062 — Primary has health=BAD (health-check worker cannot reach it) but +# IS calling node_active. No spurious failover should fire. +# +# #1032 — After a failover the old primary catches up as a secondary while +# the health checker is still marking it BAD (recovery in progress). +# With the original bug the catchingup→secondary transition was +# permanently blocked. The fix unblocks it. + +scenario { + formation { + node1 + node2 + } +} + +setup { + # Bootstrap the two-node formation from scratch using node_active calls. + # In scenario mode there are no keepers; we drive the monitor FSM directly. + node_active { node1 reported: init lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: single } + node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: single } + node_active { node2 reported: init lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: wait_standby } + node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: wait_standby } + node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: wait_primary } + node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: wait_primary } + node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: catchingup } + node_active { node2 reported: catchingup lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } + node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: primary } +} + +teardown { + compose down +} + +# ───────────────────────────────────────────────────────────────────────────── +# test_001 — stable baseline +# ───────────────────────────────────────────────────────────────────────────── +step test_001_steady_state { + node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: primary } + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } +} + +# ───────────────────────────────────────────────────────────────────────────── +# test_002 — issue #1062 +# +# Health checker marks primary BAD while the primary is still calling +# node_active. NodeIsUnhealthy is false (reportTime is fresh and pgIsRunning +# is true), so no failover must be triggered. +# ───────────────────────────────────────────────────────────────────────────── +step test_002_health_flap_no_failover { + mark unhealthy: node1 + + # Primary has health=BAD but reports pgRunning=true. + # NodeIsUnhealthy(node1) is false because reportTime is fresh and + # pgIsRunning is true — no draining must be assigned. + node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: primary } + + # Secondary calls in: failover rule requires NodeIsUnhealthy(primary) + # which is still false here, so no prepare_promotion. + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } + + mark healthy: node1 +} + +# ───────────────────────────────────────────────────────────────────────────── +# test_003 — drive a complete two-node failover +# +# node1 reports pgRunning=false (hard failure). The failover trigger fires on +# node2's heartbeat. Steps follow the state machine in order so that each +# IsCurrentState() guard is satisfied before the next transition. +# ───────────────────────────────────────────────────────────────────────────── +step test_003_failover { + mark unhealthy: node1 + + # Primary's own heartbeat — in the 2-node case ProceedGroupStateForPrimaryNode + # has no self-demotion rule; the failover is triggered from the standby side. + node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: false } + expect { assigned: primary } + + # Secondary heartbeat: NodeIsUnhealthy(node1) is true (pgIsRunning=false). + # Monitor assigns: node2=prepare_promotion, node1=draining. + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: prepare_promotion } + + # node2 converges to prepare_promotion. + # Monitor assigns: node2=stop_replication, node1=demote_timeout. + node_active { node2 reported: prepare_promotion lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: stop_replication } + + # node1 reports demote_timeout — this sets reportedState in the DB so that + # the next node2 heartbeat can satisfy IsCurrentState(node1, DEMOTE_TIMEOUT). + node_active { node1 reported: demote_timeout lsn: 0/5000 tli: 1 pgrunning: false } + expect { assigned: demote_timeout } + + # node2 reports stop_replication. + # IsCurrentState(node1, DEMOTE_TIMEOUT) is now true (see above). + # Monitor assigns: node2=wait_primary, node1=demoted. + node_active { node2 reported: stop_replication lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: wait_primary } + + # node2 in wait_primary with no secondary yet — stays wait_primary. + node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: wait_primary } +} + +# ───────────────────────────────────────────────────────────────────────────── +# test_004 — issue #1032 +# +# Old primary (node1) recovers after the failover. It resurfaces still +# reporting "primary" (the keeper never applied the demotion during the +# outage), then works through demoted → catchingup → secondary. +# +# Key assertion (issue #1032 + #1062 combined): +# After the health checker marks node1 BAD again (recovery still in +# progress), node1 calls node_active reporting "catchingup" with +# pgRunning=true. The fixed NodeIsHealthy() recognises the fresh report +# as evidence of liveness and allows catchingup→secondary to proceed. +# With the original bug (NodeIsHealthy always returned false for health=BAD +# nodes) this transition was permanently blocked. +# ───────────────────────────────────────────────────────────────────────────── +step test_004_old_primary_resurfaces { + mark healthy: node1 + + # Old primary reports "primary" while its goal state is DEMOTED. + # IsCurrentState(node1, DEMOTED) is false (reportedState mismatch) so no + # DEMOTED rule fires; monitor returns the current goalState = demoted. + node_active { node1 reported: primary lsn: 0/4F00 tli: 1 pgrunning: true } + expect { assigned: demoted } + + # Keeper has applied demotion; monitor can now assign catchingup. + node_active { node1 reported: demoted lsn: 0/4F00 tli: 1 pgrunning: false } + expect { assigned: catchingup } + + # Simulate health checker still marking node1 bad (recovery in progress). + # This is the exact condition that blocked catchingup→secondary with the + # original IsHealthy bug. + mark unhealthy: node1 + + # node1 has caught up and calls node_active with pgRunning=true. + # NodeIsHealthy(node1) must return true via the fresh-report override: + # health=BAD, healthCheckTime < reportTime, reportTime within 1 s of now. + # The catchingup→secondary rule then fires (TLI matches, LSN within threshold). + node_active { node1 reported: catchingup lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: secondary } + + # node1 confirms secondary state. + node_active { node1 reported: secondary lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: secondary } + + # node2 now has a healthy secondary in the quorum → promoted to primary. + node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: primary } +} + +sequence + test_001_steady_state + test_002_health_flap_no_failover + test_003_failover + test_004_old_primary_resurfaces diff --git a/tests/tap/specs/node_active_protocol.pgaf b/tests/tap/specs/node_active_protocol.pgaf index 1cb0f0317..49e8c2f8d 100644 --- a/tests/tap/specs/node_active_protocol.pgaf +++ b/tests/tap/specs/node_active_protocol.pgaf @@ -9,8 +9,7 @@ # updates the monitor's health table, simulating what the health-check # worker does. -cluster { - monitor +scenario { formation { node1 node2 @@ -18,11 +17,45 @@ cluster { } setup { - wait until node1 state is single timeout 60s - exec node1 pg_autoctl node start - wait until node1 state is primary - and node2 state is secondary - timeout 90s + # Bootstrap the two-node formation from scratch using node_active calls. + # In scenario mode there are no keepers; we drive the monitor FSM directly. + # IsCurrentState(node, S) requires goal == S AND reported == S, so every + # intermediate state must be explicitly confirmed before the next guard fires. + + # node1 auto-registers (goal=single); report init → assigned single + node_active { node1 reported: init lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: single } + # Confirm single so IsCurrentState(node1, SINGLE) becomes true + node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: single } + # node2 auto-registers (goal=wait_standby); report init → assigned wait_standby + # pgrunning: true throughout setup — ProceedGroupState reads pgIsRunning from the + # struct loaded at the START of each node_active call (not from the current report), + # so leaving pgIsRunning=false in the DB blocks the catchingup→secondary transition. + node_active { node2 reported: init lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: wait_standby } + # Confirm wait_standby so IsCurrentState(node2, WAIT_STANDBY) becomes true + node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: wait_standby } + # node1 calls node_active: ProceedGroupStateForPrimaryNode sees node2 in + # WAIT_STANDBY → single→wait_primary fires + node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: wait_primary } + # Confirm wait_primary so IsCurrentState(node1, WAIT_PRIMARY) becomes true + node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: wait_primary } + # node2 calls node_active: wait_standby→catchingup fires (primary confirmed) + node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } + expect { assigned: catchingup } + # node2 reports catchingup with matching LSN → secondary assigned + node_active { node2 reported: catchingup lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } + # Confirm secondary so IsCurrentState(node2, SECONDARY) becomes true + node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: secondary } + # node1 calls node_active: secondaryQuorumCount=1 → wait_primary→primary fires + node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: primary } } teardown { @@ -40,6 +73,9 @@ step test_001_steady_state { # secondary reports its current state; monitor should keep assigning secondary node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } expect { assigned: secondary } + + # confirm stable baseline: both nodes should be in their expected assigned states + assert states { node1: primary node2: secondary } } # ------------------------------------------------------------------ @@ -49,29 +85,66 @@ step test_002_primary_failure { # Mark node1 as unhealthy (simulates health-check worker detecting a failure) mark unhealthy: node1 - # node1 stops reporting (pgrunning false); monitor should move to draining + # node1's own heartbeat — in the 2-node case ProceedGroupStateForPrimaryNode + # has no self-demotion rule; draining is assigned by the secondary's heartbeat. node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: false } - expect { assigned: draining } + expect { assigned: primary } - # node2, still healthy, reports secondary; monitor should start promoting it + # node2 calls in: NodeIsUnhealthy(node1) is true (pgIsRunning=false). + # Monitor assigns node2=prepare_promotion and node1=draining. node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } expect { assigned: prepare_promotion } + assert states { node1: draining } } # ------------------------------------------------------------------ -# test_003: restore node1 as secondary after failover completes +# test_003: drive the failover to completion and restore node1 +# +# Each step reports the state the keeper has converged to; the monitor +# replies with the next goal state. IsCurrentState() guards require +# both goalState and reportedState to match, so the sequence cannot +# skip intermediate states. # ------------------------------------------------------------------ step test_003_post_failover { - # node2 completes promotion + # node2 converges to prepare_promotion. + # Monitor assigns node2=stop_replication, node1=demote_timeout. + node_active { node2 reported: prepare_promotion lsn: 0/5000 tli: 1 pgrunning: true } + expect { assigned: stop_replication } + assert states { node1: demote_timeout } + + # node1 reports demote_timeout — sets reportedState so that the next + # node2 call can satisfy IsCurrentState(node1, DEMOTE_TIMEOUT). + node_active { node1 reported: demote_timeout lsn: 0/5000 tli: 1 pgrunning: false } + expect { assigned: demote_timeout } + + # node2 converges to stop_replication. + # Monitor assigns node2=wait_primary, node1=demoted. + node_active { node2 reported: stop_replication lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: wait_primary } + assert states { node1: demoted } + + # node2 in wait_primary — no secondary in quorum yet, stays wait_primary. node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: primary } + expect { assigned: wait_primary } - # Restore node1 health so it can rejoin as secondary + # Restore node1 so it can rejoin. mark healthy: node1 - # node1 reconnects, reports demoted; monitor assigns catchingup + # node1 reports demoted; monitor assigns catchingup + # (IsCurrentState(node2, WAIT_PRIMARY) is true, NodeIsHealthy(node2) is true). node_active { node1 reported: demoted lsn: 0/4F00 tli: 1 pgrunning: false } expect { assigned: catchingup } + + # node1 catches up to the new timeline. + node_active { node1 reported: catchingup lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: secondary } + + # node1 confirms secondary; node2 can now transition to primary. + node_active { node1 reported: secondary lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: secondary } + + node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } + expect { assigned: primary } } sequence From baf3434f98c8d136bdd85b42de3c83a3b7281a37 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 01:49:33 +0200 Subject: [PATCH 05/14] monitor: replace scenario-mode pgaf specs with SQL regression test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two .pgaf scenario files (node_active_protocol.pgaf and monitor_fsm_health.pgaf) exercised the monitor's node_active() FSM through pgaftest's scenario mode, which spins up a Docker monitor container and drives it via a custom DSL runner. The same test coverage is provided more simply by a pg_regress SQL file that calls the SQL functions directly. The comparison: scenario .pgaf SQL regression ─────────────────────────── ─────────────────────────────────────────── Docker + compose required pg_regress (ships with PostgreSQL) ~20 s startup < 1 s mark healthy/unhealthy via UPDATE pgautofailover.node SET health = 0 docker exec + psql WHERE nodename = 'node1' goal-state string only exact diff of all returned columns custom DSL runner (~10k C) plain SQL The new src/monitor/sql/node_active_protocol.sql: - Bootstraps a two-node 'fsm_test' formation through all FSM states, ending at primary/secondary. This exercises the NODE_HEALTH_UNKNOWN fix (NodeIsHealthy must trust pgIsRunning when health=-1, the table default for newly registered nodes). - Verifies issue #1062: health=BAD + pgIsRunning=true keeps primary assigned primary (fresh-report override in NodeIsHealthy). - Drives a complete two-node failover (primary → prepare_promotion → stop_replication → wait_primary; old primary → demote_timeout → demoted). - Verifies issue #1032: old primary recovers with health still BAD; reports catchingup with pgIsRunning=true; the stale in-memory struct fix ensures ProceedGroupState sees the updated pgIsRunning, and the fresh-report override in NodeIsHealthy allows catchingup→secondary. The C fixes from the previous commit are unchanged: src/monitor/node_metadata.c NodeIsHealthy: handle NODE_HEALTH_UNKNOWN src/monitor/node_active_protocol.c sync pgIsRunning/reportedTLI/reportTime into struct after ReportAutoFailoverNodeState The pgaftest files reverted to their state at fc09d6c (before scenario-mode DSL commands were added): src/bin/pgaftest/test_runner.c src/bin/pgaftest/test_spec.h src/bin/pgaftest/test_spec_parse.{c,h,y} src/bin/pgaftest/test_spec_scan.{c,l} src/bin/pgaftest/compose_gen.c --- src/bin/pgaftest/compose_gen.c | 290 +- src/bin/pgaftest/test_runner.c | 383 --- src/bin/pgaftest/test_spec.h | 37 - src/bin/pgaftest/test_spec_parse.c | 2402 ++++++++-------- src/bin/pgaftest/test_spec_parse.h | 430 ++- src/bin/pgaftest/test_spec_parse.y | 144 +- src/bin/pgaftest/test_spec_scan.c | 2519 ++++++++++------- src/bin/pgaftest/test_spec_scan.l | 13 +- src/monitor/Makefile | 2 +- src/monitor/expected/node_active_protocol.out | 420 +++ src/monitor/sql/node_active_protocol.sql | 270 ++ tests/tap/specs/monitor_fsm_health.pgaf | 198 -- tests/tap/specs/node_active_protocol.pgaf | 153 - 13 files changed, 3593 insertions(+), 3668 deletions(-) create mode 100644 src/monitor/expected/node_active_protocol.out create mode 100644 src/monitor/sql/node_active_protocol.sql delete mode 100644 tests/tap/specs/monitor_fsm_health.pgaf delete mode 100644 tests/tap/specs/node_active_protocol.pgaf diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index 77234f1ac..e993d8963 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -648,155 +648,154 @@ compose_gen_write(TestCluster *cluster, /* ---- data nodes — iterate all formations ---- */ /* - * In scenario (monitor-API-only) mode, nodes are virtual: only names used - * in node_active calls. No data-node containers are generated. + * Non-default formations are listed in [formation ] sections of the + * monitor.ini. pg_autoctl node run reads them and creates each one after + * the monitor is initialized, before starting the supervisor. + * Data nodes retry registration until their formation exists. */ const TestNode *firstNode = NULL; - if (!cluster->monitorApiOnly) + for (int fi = 0; fi < cluster->formationCount; fi++) { - for (int fi = 0; fi < cluster->formationCount; fi++) + const TestFormation *form = &cluster->formations[fi]; + + for (int ni = 0; ni < form->nodeCount; ni++) { - const TestFormation *form = &cluster->formations[fi]; + const TestNode *n = &form->nodes[ni]; + fformat(f, " %s:\n", n->name); + if (n->debianCluster[0]) + { + write_image_stanza_target(f, cluster, contextDir, "debian"); + } + else + { + write_image_stanza(f, cluster, contextDir); + } - for (int ni = 0; ni < form->nodeCount; ni++) + /* debian PGDATA: /var/lib/postgresql// */ + char node_pgdata[MAXPGPATH]; + if (n->debianCluster[0]) { - const TestNode *n = &form->nodes[ni]; - fformat(f, " %s:\n", n->name); - if (n->debianCluster[0]) - { - write_image_stanza_target(f, cluster, contextDir, "debian"); - } - else - { - write_image_stanza(f, cluster, contextDir); - } - - /* debian PGDATA: /var/lib/postgresql// */ - char node_pgdata[MAXPGPATH]; - if (n->debianCluster[0]) - { - sformat(node_pgdata, sizeof(node_pgdata), - DEBIAN_PGDATA_PREFIX "/%s/%s", - debian_pg_version(), n->debianCluster); - } - else - { - strlcpy(node_pgdata, NODE_PGDATA, sizeof(node_pgdata)); - } + sformat(node_pgdata, sizeof(node_pgdata), + DEBIAN_PGDATA_PREFIX "/%s/%s", + debian_pg_version(), n->debianCluster); + } + else + { + strlcpy(node_pgdata, NODE_PGDATA, sizeof(node_pgdata)); + } + fformat(f, + " hostname: %s\n" + " volumes:\n" + " - %s_data:/var/lib/postgres:rw\n" + " - ./%s.ini:" NODE_INI_PATH ":%s\n", + n->name, + n->name, + n->name, + n->launchDeferred ? "rw" : "ro"); + if (ssl_needs_certs(cluster->ssl)) + { fformat(f, - " hostname: %s\n" - " volumes:\n" - " - %s_data:/var/lib/postgres:rw\n" - " - ./%s.ini:" NODE_INI_PATH ":%s\n", - n->name, - n->name, - n->name, - n->launchDeferred ? "rw" : "ro"); - if (ssl_needs_certs(cluster->ssl)) - { - fformat(f, - " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" - " - ./ssl/%s:" - SSL_DIR_IN_CONTAINER "/server:ro\n" - " - ./ssl/client:" - SSL_DIR_IN_CONTAINER "/client:ro\n", - n->name); - } - for (int vi = 0; vi < n->volumeCount; vi++) - { - fformat(f, " - %s_%s:%s:rw\n", - n->volumes[vi].name, n->name, n->volumes[vi].path); - } - if (specDir && specDir[0]) - { - fformat(f, - " - %s:/etc/pgaf/specs:ro\n", specDir); - } + " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" + " - ./ssl/%s:" + SSL_DIR_IN_CONTAINER "/server:ro\n" + " - ./ssl/client:" + SSL_DIR_IN_CONTAINER "/client:ro\n", + n->name); + } + for (int vi = 0; vi < n->volumeCount; vi++) + { + fformat(f, " - %s_%s:%s:rw\n", + n->volumes[vi].name, n->name, n->volumes[vi].path); + } + if (specDir && specDir[0]) + { fformat(f, - " environment:\n" - " PGDATA: %s\n" - " PGUSER: demo\n" - " PGDATABASE: demo\n" - " PG_AUTOCTL_TEST_DELAY: \"1\"\n" - " expose:\n" - " - 5432\n", - node_pgdata); + " - %s:/etc/pgaf/specs:ro\n", specDir); + } + fformat(f, + " environment:\n" + " PGDATA: %s\n" + " PGUSER: demo\n" + " PGDATABASE: demo\n" + " PG_AUTOCTL_TEST_DELAY: \"1\"\n" + " expose:\n" + " - 5432\n", + node_pgdata); + + /* + * No depends_on: keeper retry loops handle monitor not yet ready, + * and the formation wait in keeper_register_and_init handles the + * case where the formation hasn't been created yet. + */ + /* per-node ssl override may differ from cluster default */ + const char *node_ssl = n->ssl[0] ? n->ssl : cluster->ssl; + fformat(f, + " command: [\"/bin/sh\", \"-c\"," + " \"%s rm -f /tmp/pg_autoctl%s/pg_autoctl.pid" + " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" + " stop_grace_period: 60s\n", + ssl_needs_certs(node_ssl) ? SSL_COPY_CERTS_CMD : "", + node_pgdata); + + /* + * With a monitor: the first data node gets a healthcheck so that + * subsequent nodes use service_healthy depends_on. This ensures + * node1 has registered with the monitor (and become the initial + * primary) before any other node starts, making the initial + * election deterministic. + * + * Without a monitor (no-monitor nodes): the FSM is driven + * manually via pg_autoctl manual fsm assign, so postgres is not + * running when the container starts. No healthcheck; subsequent + * nodes use service_started so they launch as soon as node1 has + * started (they don't need postgres to be ready yet). + */ + if (!firstNode && cluster->withMonitor && !n->launchDeferred) + { /* - * No depends_on: keeper retry loops handle monitor not yet ready, - * and the formation wait in keeper_register_and_init handles the - * case where the formation hasn't been created yet. + * SSL clusters take longer to initialise on slow CI runners + * (cert generation + pg_autoctl SSL config + monitor TLS + * handshake). Double start_period so the runner has time to + * complete init before failures start counting. */ + const char *hc_start = + ssl_needs_certs(node_ssl) ? "300s" : "120s"; + fformat(f, + " healthcheck:\n" + " test: [\"CMD\", \"pg_autoctl\", \"status\"," + " \"--pgdata\", \"%s\"]\n" + " interval: 2s\n" + " timeout: 5s\n" + " retries: 150\n" + " start_period: %s\n", + node_pgdata, hc_start); + } - /* per-node ssl override may differ from cluster default */ - const char *node_ssl = n->ssl[0] ? n->ssl : cluster->ssl; + if (firstNode) + { + fformat(f, + " depends_on:\n" + " %s:\n" + " condition: %s\n", + firstNode->name, + cluster->withMonitor ? "service_healthy" : "service_started"); + } + else if (cluster->withMonitor && !n->launchDeferred) + { + /* node1: wait for monitor to be healthy before starting */ fformat(f, - " command: [\"/bin/sh\", \"-c\"," - " \"%s rm -f /tmp/pg_autoctl%s/pg_autoctl.pid" - " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" - " stop_grace_period: 60s\n", - ssl_needs_certs(node_ssl) ? SSL_COPY_CERTS_CMD : "", - node_pgdata); + " depends_on:\n" + " monitor:\n" + " condition: service_healthy\n"); + } + fformat(f, "\n"); - /* - * With a monitor: the first data node gets a healthcheck so that - * subsequent nodes use service_healthy depends_on. This ensures - * node1 has registered with the monitor (and become the initial - * primary) before any other node starts, making the initial - * election deterministic. - * - * Without a monitor (no-monitor nodes): the FSM is driven - * manually via pg_autoctl manual fsm assign, so postgres is not - * running when the container starts. No healthcheck; subsequent - * nodes use service_started so they launch as soon as node1 has - * started (they don't need postgres to be ready yet). - */ - if (!firstNode && cluster->withMonitor && !n->launchDeferred) - { - /* - * SSL clusters take longer to initialise on slow CI runners - * (cert generation + pg_autoctl SSL config + monitor TLS - * handshake). Double start_period so the runner has time to - * complete init before failures start counting. - */ - const char *hc_start = - ssl_needs_certs(node_ssl) ? "300s" : "120s"; - fformat(f, - " healthcheck:\n" - " test: [\"CMD\", \"pg_autoctl\", \"status\"," - " \"--pgdata\", \"%s\"]\n" - " interval: 2s\n" - " timeout: 5s\n" - " retries: 150\n" - " start_period: %s\n", - node_pgdata, hc_start); - } - - if (firstNode) - { - fformat(f, - " depends_on:\n" - " %s:\n" - " condition: %s\n", - firstNode->name, - cluster->withMonitor ? "service_healthy" : "service_started"); - } - else if (cluster->withMonitor && !n->launchDeferred) - { - /* node1: wait for monitor to be healthy before starting */ - fformat(f, - " depends_on:\n" - " monitor:\n" - " condition: service_healthy\n"); - } - fformat(f, "\n"); - - if (!firstNode && !n->launchDeferred) - { - firstNode = n; - } + if (!firstNode && !n->launchDeferred) + { + firstNode = n; } } } @@ -888,14 +887,6 @@ compose_gen_write(TestCluster *cluster, " condition: service_healthy\n", firstNode->name); } - else if (cluster->monitorApiOnly && cluster->withMonitor) - { - /* scenario mode: no data nodes, wait for monitor only */ - fformat(f, - " depends_on:\n" - " monitor:\n" - " condition: service_healthy\n"); - } fformat(f, " command: [\"pgaftest\", \"run\", \"/spec.pgaf\"]\n\n"); } @@ -909,19 +900,16 @@ compose_gen_write(TestCluster *cluster, { fformat(f, " %s_data:\n", cluster->secondMonitorName); } - if (!cluster->monitorApiOnly) + for (int fi = 0; fi < cluster->formationCount; fi++) { - for (int fi = 0; fi < cluster->formationCount; fi++) + const TestFormation *form = &cluster->formations[fi]; + for (int ni = 0; ni < form->nodeCount; ni++) { - const TestFormation *form = &cluster->formations[fi]; - for (int ni = 0; ni < form->nodeCount; ni++) + const TestNode *n = &form->nodes[ni]; + fformat(f, " %s_data:\n", n->name); + for (int vi = 0; vi < n->volumeCount; vi++) { - const TestNode *n = &form->nodes[ni]; - fformat(f, " %s_data:\n", n->name); - for (int vi = 0; vi < n->volumeCount; vi++) - { - fformat(f, " %s_%s:\n", n->volumes[vi].name, n->name); - } + fformat(f, " %s_%s:\n", n->volumes[vi].name, n->name); } } } diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index f5b1f300b..675c012e2 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -2378,14 +2378,6 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) case CMD_WAIT_STATE: { - if (r->spec->cluster.monitorApiOnly) - { - sformat(errBuf, errLen, - "wait until is not supported in scenario mode; " - "use node_active calls in setup to drive state"); - return false; - } - /* * LISTEN-driven wait (items 5 & 6). * @@ -2505,41 +2497,6 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) return true; } - case CMD_ASSERT_STATES: - { - /* - * Synchronous multi-node goalstate check. - * Calls monitor_get_node_state() for each (name, expected) pair - * and fails immediately if any mismatch is found. - */ - bool ok = true; - for (int i = 0; i < cmd->waitStateCount; i++) - { - char reported[64] = "", assigned[64] = ""; - if (!monitor_get_node_state(r, cmd->waitNodes[i], - reported, sizeof(reported), - assigned, sizeof(assigned))) - { - sformat(errBuf, errLen, - "assert states: cannot reach monitor " - "to check state of node '%s'", - cmd->waitNodes[i]); - ok = false; - break; - } - if (strcmp(assigned, cmd->waitStates[i]) != 0) - { - sformat(errBuf, errLen, - "assert states: %s assigned-state is \"%s\", " - "expected \"%s\"", - cmd->waitNodes[i], assigned, cmd->waitStates[i]); - ok = false; - break; - } - } - return ok; - } - case CMD_SQL: { strlcpy(r->lastSqlService, cmd->service, sizeof(r->lastSqlService)); @@ -2811,14 +2768,6 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) */ case CMD_WAIT_MULTI: { - if (r->spec->cluster.monitorApiOnly) - { - sformat(errBuf, errLen, - "wait until is not supported in scenario mode; " - "use node_active calls in setup to drive state"); - return false; - } - runner_notify_connect(r); int timeoutSecs = cmd->timeoutSeconds; @@ -3205,317 +3154,6 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) return true; } - case CMD_NODE_ACTIVE: - { - /* - * Monitor node_active protocol test. - * - * Parse the raw block: "node2 reported: secondary lsn: 0/5A0 - * tli: 1 pgrunning: true" - * and the expect block: "assigned: secondary" - * - * Then: - * 1. Look up node_id from pgautofailover.node. - * 2. Call pgautofailover.node_active(...) on the monitor. - * 3. Assert the returned assigned state matches nodeActiveExpected. - */ - char nodeName[64] = { 0 }; - char reported[64] = "secondary"; - char lsn[32] = "0/0"; - int tli = 1; - int pgrunning = 1; - - /* Parse raw block content into key-value pairs */ - { - char buf[sizeof(cmd->args)]; - strlcpy(buf, cmd->args, sizeof(buf)); - - /* First token before any ':' is the node name */ - char *p = buf; - while (*p == ' ' || *p == '\t') - { - p++; - } - char *nameEnd = p; - while (*nameEnd && *nameEnd != ' ' && *nameEnd != '\t') - { - nameEnd++; - } - size_t nameLen = nameEnd - p; - if (nameLen >= sizeof(nodeName)) - { - nameLen = sizeof(nodeName) - 1; - } - memcpy(nodeName, p, nameLen); - nodeName[nameLen] = '\0'; - p = nameEnd; - - /* Parse remaining key: value pairs */ - while (*p) - { - while (*p == ' ' || *p == '\t') - { - p++; - } - char *kstart = p; - while (*p && *p != ':') - { - p++; - } - if (*p != ':') - { - break; - } - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - { - p++; - } - char *vstart = p; - while (*p && *p != ' ' && *p != '\t' && *p != '\n') - { - p++; - } - if (*p) - { - *p++ = '\0'; - } - - /* trim trailing whitespace from key */ - char *kt = kstart + strlen(kstart) - 1; - while (kt >= kstart && (*kt == ' ' || *kt == '\t')) - { - *kt-- = '\0'; - } - - if (strcmp(kstart, "reported") == 0) - { - strlcpy(reported, vstart, sizeof(reported)); - } - else if (strcmp(kstart, "lsn") == 0) - { - strlcpy(lsn, vstart, sizeof(lsn)); - } - else if (strcmp(kstart, "tli") == 0) - { - tli = atoi(vstart); - } - else if (strcmp(kstart, "pgrunning") == 0) - { - pgrunning = (strcmp(vstart, "true") == 0 || - strcmp(vstart, "1") == 0) ? 1 : 0; - } - } - } - - /* Parse expected: "assigned: secondary" */ - char expectedState[64] = { 0 }; - { - const char *p = cmd->nodeActiveExpected; - while (*p == ' ' || *p == '\t') - { - p++; - } - if (strncmp(p, "assigned:", 9) == 0) - { - p += 9; - while (*p == ' ' || *p == '\t') - { - p++; - } - strlcpy(expectedState, p, sizeof(expectedState)); - - /* trim trailing whitespace */ - char *e = expectedState + strlen(expectedState) - 1; - while (e >= expectedState && (*e == ' ' || *e == '\t' || *e == '\n')) - { - *e-- = '\0'; - } - } - } - - if (nodeName[0] == '\0' || expectedState[0] == '\0') - { - sformat(errBuf, errLen, - "node_active: failed to parse command " - "(args=%s expect=%s)", - cmd->args, cmd->nodeActiveExpected); - return false; - } - - log_info(" node_active: node=%s reported=%s lsn=%s tli=%d " - "pgrunning=%s expect assigned=%s", - nodeName, reported, lsn, tli, - pgrunning ? "true" : "false", expectedState); - - /* - * Step 1: resolve node_id + group_id from the monitor. - */ - char lookupSql[512]; - char nodeInfo[256] = { 0 }; - sformat(lookupSql, sizeof(lookupSql), - "SELECT nodeid || '|' || groupid " - "FROM pgautofailover.node " - "WHERE nodename = '%s' LIMIT 1", - nodeName); - - if (!exec_sql_on_service(r, "monitor", - lookupSql, nodeInfo, sizeof(nodeInfo))) - { - sformat(errBuf, errLen, - "node_active: could not look up node '%s' on monitor", - nodeName); - return false; - } - - /* strip trailing newline */ - char *nl = strchr(nodeInfo, '\n'); - if (nl) - { - *nl = '\0'; - } - - /* - * Empty result means the node is not registered yet. In scenario - * mode, virtual nodes are auto-registered on first contact so that - * setup blocks can drive the FSM from scratch using node_active - * calls without needing real pg_autoctl keepers. - */ - if (nodeInfo[0] == '\0' && r->spec->cluster.monitorApiOnly) - { - char regSql[512]; - char regResult[256] = { 0 }; - - /* - * Pass sysidentifier=1 (non-zero) so the check constraint - * "system_identifier_is_null_at_init_only" does not fire - * when reportedstate later advances past 'init'. All - * virtual nodes in the same group get the same value, - * which also satisfies same_system_identifier_within_group. - */ - sformat(regSql, sizeof(regSql), - "SELECT assigned_node_id || '|' || assigned_group_id " - "FROM pgautofailover.register_node(" - "'default', '%s', 5432, 'pg_auto_failover', '%s', 1)", - nodeName, nodeName); - - if (!exec_sql_on_service(r, "monitor", regSql, - regResult, sizeof(regResult))) - { - sformat(errBuf, errLen, - "node_active: auto-register failed for node '%s'", - nodeName); - return false; - } - - char *nl2 = strchr(regResult, '\n'); - if (nl2) - { - *nl2 = '\0'; - } - strlcpy(nodeInfo, regResult, sizeof(nodeInfo)); - log_info(" node_active: registered node '%s' as %s", - nodeName, nodeInfo); - } - - long long nodeId = 0; - int groupId = 0; - if (sscanf(nodeInfo, "%lld|%d", &nodeId, &groupId) != 2) - { - sformat(errBuf, errLen, - "node_active: unexpected node lookup result: '%s'", - nodeInfo); - return false; - } - - /* - * Step 2: call pgautofailover.node_active() and capture the - * assigned_group_state column. - */ - char callSql[1024]; - sformat(callSql, sizeof(callSql), - "SELECT assigned_group_state " - "FROM pgautofailover.node_active(" - "'default', %lld, %d, '%s', %s, %d, '%s', '')", - nodeId, groupId, - reported, - pgrunning ? "true" : "false", - tli, lsn); - - char assignedState[256] = { 0 }; - if (!exec_sql_on_service(r, "monitor", - callSql, assignedState, sizeof(assignedState))) - { - sformat(errBuf, errLen, - "node_active: call failed for node '%s': %s", - nodeName, assignedState); - return false; - } - - /* strip trailing whitespace */ - nl = assignedState + strlen(assignedState); - while (nl > assignedState && - (nl[-1] == '\n' || nl[-1] == '\r' || nl[-1] == ' ')) - { - *--nl = '\0'; - } - - if (strcmp(assignedState, expectedState) != 0) - { - sformat(errBuf, errLen, - "node_active: expected assigned='%s', got '%s'", - expectedState, assignedState); - return false; - } - return true; - } - - case CMD_MARK_HEALTH: - { - /* - * mark healthy/unhealthy: - * - * Directly update the health column in pgautofailover.node on the - * monitor. health=1 (NODE_HEALTH_GOOD), health=0 (NODE_HEALTH_BAD). - * - * Must run as the docker OS user (PostgreSQL superuser via peer - * auth) because autoctl_node lacks write access to this table. - */ - int healthValue = cmd->markHealthy ? 1 : 0; - char updateSql[512]; - sformat(updateSql, sizeof(updateSql), - "UPDATE pgautofailover.node " - "SET health = %d, healthchecktime = now() " - "WHERE nodename = \'%s\'", - healthValue, cmd->service); - - char escapedSql[1024]; - escape_sql_for_shell(updateSql, escapedSql, sizeof(escapedSql)); - - char out[256] = { 0 }; - int rc_health = run_cmd_capture(out, sizeof(out), - "%s exec -T -u docker %s " - "psql --tuples-only --no-align " - "-v ON_ERROR_STOP=1 -v VERBOSITY=verbose " - "-d pg_auto_failover -c '%s' 2>&1", - r->composeBase, r->activeMonitorService, - escapedSql); - - if (rc_health != 0) - { - sformat(errBuf, errLen, - "mark %s: UPDATE failed for node '%s': %s", - cmd->markHealthy ? "healthy" : "unhealthy", - cmd->service, out); - return false; - } - - log_info(" mark %s: node=%s", - cmd->markHealthy ? "healthy" : "unhealthy", - cmd->service); - return true; - } - case CMD_LOGS_CHECK: { /* @@ -3721,12 +3359,6 @@ cmd_label(const TestCmd *cmd, char *buf, int len) break; } - case CMD_ASSERT_STATES: - { - sformat(buf, len, "assert states { %d nodes }", cmd->waitStateCount); - break; - } - case CMD_PROMOTE: { char nodes[256] = ""; @@ -3902,21 +3534,6 @@ cmd_label(const TestCmd *cmd, char *buf, int len) break; } - case CMD_NODE_ACTIVE: - { - sformat(buf, len, "node_active { %s } expect { %s }", - cmd->args, cmd->nodeActiveExpected); - break; - } - - case CMD_MARK_HEALTH: - { - sformat(buf, len, "mark %s: %s", - cmd->markHealthy ? "healthy" : "unhealthy", - cmd->service); - break; - } - default: { sformat(buf, len, "(unknown command %d)", cmd->kind); diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index 4917662aa..4446de914 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -119,14 +119,6 @@ typedef struct TestCluster char monitorDebianCluster[64]; /* debian-cluster name for the monitor, "" otherwise */ char monitorImageTarget[64]; /* Dockerfile build target for monitor; "" = "run" */ - - /* - * When true the spec was declared with the "scenario { }" keyword rather - * than "cluster { }". Only a monitor service is provisioned; nodes are - * virtual (names only, no containers). node_active and mark_health - * commands are restricted to this mode. - */ - bool monitorApiOnly; } TestCluster; /* ----------------------------------------------------------------------- @@ -170,24 +162,6 @@ typedef enum TestCmdKind CMD_SET_MONITOR, /* set monitor — switch active monitor service */ CMD_LOGS_CHECK, /* logs [not] — grep container logs */ CMD_COMPOSE_INJECT, /* compose inject : */ - - /* - * Monitor node_active protocol tests. - * - * node_active { reported: lsn: [tli: N] [pgrunning: bool] } - * expect { assigned: } - * - * Calls pgautofailover.node_active() on the monitor with the given - * parameters and asserts the returned assigned state. - * - * mark healthy: — set node health to GOOD (healthchecktime = now) - * mark unhealthy: — set node health to BAD (healthchecktime = now) - */ - CMD_NODE_ACTIVE, /* node_active { ... } expect { assigned: ... } */ - CMD_MARK_HEALTH, /* mark [un]healthy: */ - - /* assert states { node1: X node2: Y } — sync multi-node goalstate check */ - CMD_ASSERT_STATES, } TestCmdKind; typedef struct TestCmd @@ -231,17 +205,6 @@ typedef struct TestCmd /* CMD_LOGS_CHECK */ bool logsNegate; /* true → assert pattern NOT found */ - /* CMD_NODE_ACTIVE */ - char nodeActiveName[64]; /* node name */ - char nodeActiveReported[64]; /* reported state string */ - char nodeActiveLsn[32]; /* LSN string, e.g. "0/5A0" */ - int nodeActiveTli; /* timeline, default 1 */ - bool nodeActivePgRunning; /* pg_is_running, default true */ - char nodeActiveExpected[64]; /* expected assigned state */ - - /* CMD_MARK_HEALTH */ - bool markHealthy; /* true → GOOD, false → BAD */ - struct TestCmd *next; } TestCmd; diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index 910171ff6..2595cab42 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -68,231 +68,219 @@ enum yytokentype { T_CLUSTER = 258, - T_SCENARIO = 259, - T_MONITOR = 260, - T_NODE = 261, - T_CITUS_COORDINATOR = 262, - T_CITUS_WORKER = 263, - T_SETUP = 264, - T_TEARDOWN = 265, - T_STEP = 266, - T_SEQUENCE = 267, - T_EQUALS = 268, - T_IMAGE = 269, - T_IMAGE_TARGET = 270, - T_SSL = 271, - T_AUTH = 272, - T_AUTH_METHOD = 273, - T_FORMATION = 274, - T_NUM_SYNC = 275, - T_COORDINATOR = 276, - T_WORKER = 277, - T_ASYNC = 278, - T_NO_MONITOR = 279, - T_LAUNCH = 280, - T_DEFERRED = 281, - T_IMMEDIATE = 282, - T_INITIALLY = 283, - T_VOLUME = 284, - T_LISTEN = 285, - T_CITUS_SECONDARY = 286, - T_CANDIDATE_PRIORITY = 287, - T_PORT = 288, - T_PASSWORD = 289, - T_MONITOR_PASSWORD = 290, - T_CITUS_CLUSTER_NAME = 291, - T_DEBIAN_CLUSTER = 292, - T_REPLICATION_QUORUM = 293, - T_REPLICATION_PASSWORD = 294, - T_EXTENSION_VERSION = 295, - T_BIND_SOURCE = 296, - T_FS_INIT = 297, - T_FS_SINGLE = 298, - T_FS_PRIMARY = 299, - T_FS_WAIT_PRIMARY = 300, - T_FS_WAIT_STANDBY = 301, - T_FS_DEMOTED = 302, - T_FS_DEMOTE_TIMEOUT = 303, - T_FS_DRAINING = 304, - T_FS_SECONDARY = 305, - T_FS_CATCHINGUP = 306, - T_FS_PREP_PROMOTION = 307, - T_FS_STOP_REPLICATION = 308, - T_FS_MAINTENANCE = 309, - T_FS_JOIN_PRIMARY = 310, - T_FS_APPLY_SETTINGS = 311, - T_FS_PREPARE_MAINTENANCE = 312, - T_FS_WAIT_MAINTENANCE = 313, - T_FS_REPORT_LSN = 314, - T_FS_FAST_FORWARD = 315, - T_FS_JOIN_SECONDARY = 316, - T_FS_DROPPED = 317, - T_EXEC = 318, - T_EXEC_FAILS = 319, - T_PG_AUTOCTL = 320, - T_WAIT = 321, - T_UNTIL = 322, - T_TIMEOUT = 323, - T_AND = 324, - T_IS = 325, - T_WITH = 326, - T_ASSERT = 327, - T_SQL = 328, - T_EXPECT = 329, - T_ERROR = 330, - T_PROMOTE = 331, - T_NETWORK = 332, - T_DISCONNECT = 333, - T_CONNECT = 334, - T_SLEEP = 335, - T_COMPOSE = 336, - T_DOWN = 337, - T_START = 338, - T_STOP = 339, - T_STOPPED = 340, - T_KILL = 341, - T_INJECT = 342, - T_STATE = 343, - T_ASSIGNED_STATE = 344, - T_IN = 345, - T_GROUP = 346, - T_LBRACE = 347, - T_RBRACE = 348, - T_COMMA = 349, - T_POSTGRES = 350, - T_STAYS = 351, - T_WHILE = 352, - T_THROUGH = 353, - T_SET = 354, - T_LOGS = 355, - T_NOT = 356, - T_CONTAINS = 357, - T_MATCHES = 358, - T_NODE_ACTIVE = 359, - T_MARK = 360, - T_HEALTHY = 361, - T_UNHEALTHY = 362, - T_STATES = 363, - T_INTEGER = 364, - T_IDENT = 365, - T_STRING = 366, - T_BLOCK = 367, - T_SHELL_ARGS = 368 + T_MONITOR = 259, + T_NODE = 260, + T_CITUS_COORDINATOR = 261, + T_CITUS_WORKER = 262, + T_SETUP = 263, + T_TEARDOWN = 264, + T_STEP = 265, + T_SEQUENCE = 266, + T_EQUALS = 267, + T_IMAGE = 268, + T_IMAGE_TARGET = 269, + T_SSL = 270, + T_AUTH = 271, + T_AUTH_METHOD = 272, + T_FORMATION = 273, + T_NUM_SYNC = 274, + T_COORDINATOR = 275, + T_WORKER = 276, + T_ASYNC = 277, + T_NO_MONITOR = 278, + T_LAUNCH = 279, + T_DEFERRED = 280, + T_IMMEDIATE = 281, + T_INITIALLY = 282, + T_VOLUME = 283, + T_LISTEN = 284, + T_CITUS_SECONDARY = 285, + T_CANDIDATE_PRIORITY = 286, + T_PORT = 287, + T_PASSWORD = 288, + T_MONITOR_PASSWORD = 289, + T_CITUS_CLUSTER_NAME = 290, + T_DEBIAN_CLUSTER = 291, + T_REPLICATION_QUORUM = 292, + T_REPLICATION_PASSWORD = 293, + T_EXTENSION_VERSION = 294, + T_BIND_SOURCE = 295, + T_FS_INIT = 296, + T_FS_SINGLE = 297, + T_FS_PRIMARY = 298, + T_FS_WAIT_PRIMARY = 299, + T_FS_WAIT_STANDBY = 300, + T_FS_DEMOTED = 301, + T_FS_DEMOTE_TIMEOUT = 302, + T_FS_DRAINING = 303, + T_FS_SECONDARY = 304, + T_FS_CATCHINGUP = 305, + T_FS_PREP_PROMOTION = 306, + T_FS_STOP_REPLICATION = 307, + T_FS_MAINTENANCE = 308, + T_FS_JOIN_PRIMARY = 309, + T_FS_APPLY_SETTINGS = 310, + T_FS_PREPARE_MAINTENANCE = 311, + T_FS_WAIT_MAINTENANCE = 312, + T_FS_REPORT_LSN = 313, + T_FS_FAST_FORWARD = 314, + T_FS_JOIN_SECONDARY = 315, + T_FS_DROPPED = 316, + T_EXEC = 317, + T_EXEC_FAILS = 318, + T_PG_AUTOCTL = 319, + T_WAIT = 320, + T_UNTIL = 321, + T_TIMEOUT = 322, + T_AND = 323, + T_IS = 324, + T_WITH = 325, + T_ASSERT = 326, + T_SQL = 327, + T_EXPECT = 328, + T_ERROR = 329, + T_PROMOTE = 330, + T_NETWORK = 331, + T_DISCONNECT = 332, + T_CONNECT = 333, + T_SLEEP = 334, + T_COMPOSE = 335, + T_DOWN = 336, + T_START = 337, + T_STOP = 338, + T_STOPPED = 339, + T_KILL = 340, + T_INJECT = 341, + T_STATE = 342, + T_ASSIGNED_STATE = 343, + T_IN = 344, + T_GROUP = 345, + T_LBRACE = 346, + T_RBRACE = 347, + T_COMMA = 348, + T_POSTGRES = 349, + T_STAYS = 350, + T_WHILE = 351, + T_THROUGH = 352, + T_SET = 353, + T_LOGS = 354, + T_NOT = 355, + T_CONTAINS = 356, + T_MATCHES = 357, + T_INTEGER = 358, + T_IDENT = 359, + T_STRING = 360, + T_BLOCK = 361, + T_SHELL_ARGS = 362 }; #endif /* Tokens. */ #define T_CLUSTER 258 -#define T_SCENARIO 259 -#define T_MONITOR 260 -#define T_NODE 261 -#define T_CITUS_COORDINATOR 262 -#define T_CITUS_WORKER 263 -#define T_SETUP 264 -#define T_TEARDOWN 265 -#define T_STEP 266 -#define T_SEQUENCE 267 -#define T_EQUALS 268 -#define T_IMAGE 269 -#define T_IMAGE_TARGET 270 -#define T_SSL 271 -#define T_AUTH 272 -#define T_AUTH_METHOD 273 -#define T_FORMATION 274 -#define T_NUM_SYNC 275 -#define T_COORDINATOR 276 -#define T_WORKER 277 -#define T_ASYNC 278 -#define T_NO_MONITOR 279 -#define T_LAUNCH 280 -#define T_DEFERRED 281 -#define T_IMMEDIATE 282 -#define T_INITIALLY 283 -#define T_VOLUME 284 -#define T_LISTEN 285 -#define T_CITUS_SECONDARY 286 -#define T_CANDIDATE_PRIORITY 287 -#define T_PORT 288 -#define T_PASSWORD 289 -#define T_MONITOR_PASSWORD 290 -#define T_CITUS_CLUSTER_NAME 291 -#define T_DEBIAN_CLUSTER 292 -#define T_REPLICATION_QUORUM 293 -#define T_REPLICATION_PASSWORD 294 -#define T_EXTENSION_VERSION 295 -#define T_BIND_SOURCE 296 -#define T_FS_INIT 297 -#define T_FS_SINGLE 298 -#define T_FS_PRIMARY 299 -#define T_FS_WAIT_PRIMARY 300 -#define T_FS_WAIT_STANDBY 301 -#define T_FS_DEMOTED 302 -#define T_FS_DEMOTE_TIMEOUT 303 -#define T_FS_DRAINING 304 -#define T_FS_SECONDARY 305 -#define T_FS_CATCHINGUP 306 -#define T_FS_PREP_PROMOTION 307 -#define T_FS_STOP_REPLICATION 308 -#define T_FS_MAINTENANCE 309 -#define T_FS_JOIN_PRIMARY 310 -#define T_FS_APPLY_SETTINGS 311 -#define T_FS_PREPARE_MAINTENANCE 312 -#define T_FS_WAIT_MAINTENANCE 313 -#define T_FS_REPORT_LSN 314 -#define T_FS_FAST_FORWARD 315 -#define T_FS_JOIN_SECONDARY 316 -#define T_FS_DROPPED 317 -#define T_EXEC 318 -#define T_EXEC_FAILS 319 -#define T_PG_AUTOCTL 320 -#define T_WAIT 321 -#define T_UNTIL 322 -#define T_TIMEOUT 323 -#define T_AND 324 -#define T_IS 325 -#define T_WITH 326 -#define T_ASSERT 327 -#define T_SQL 328 -#define T_EXPECT 329 -#define T_ERROR 330 -#define T_PROMOTE 331 -#define T_NETWORK 332 -#define T_DISCONNECT 333 -#define T_CONNECT 334 -#define T_SLEEP 335 -#define T_COMPOSE 336 -#define T_DOWN 337 -#define T_START 338 -#define T_STOP 339 -#define T_STOPPED 340 -#define T_KILL 341 -#define T_INJECT 342 -#define T_STATE 343 -#define T_ASSIGNED_STATE 344 -#define T_IN 345 -#define T_GROUP 346 -#define T_LBRACE 347 -#define T_RBRACE 348 -#define T_COMMA 349 -#define T_POSTGRES 350 -#define T_STAYS 351 -#define T_WHILE 352 -#define T_THROUGH 353 -#define T_SET 354 -#define T_LOGS 355 -#define T_NOT 356 -#define T_CONTAINS 357 -#define T_MATCHES 358 -#define T_NODE_ACTIVE 359 -#define T_MARK 360 -#define T_HEALTHY 361 -#define T_UNHEALTHY 362 -#define T_STATES 363 -#define T_INTEGER 364 -#define T_IDENT 365 -#define T_STRING 366 -#define T_BLOCK 367 -#define T_SHELL_ARGS 368 +#define T_MONITOR 259 +#define T_NODE 260 +#define T_CITUS_COORDINATOR 261 +#define T_CITUS_WORKER 262 +#define T_SETUP 263 +#define T_TEARDOWN 264 +#define T_STEP 265 +#define T_SEQUENCE 266 +#define T_EQUALS 267 +#define T_IMAGE 268 +#define T_IMAGE_TARGET 269 +#define T_SSL 270 +#define T_AUTH 271 +#define T_AUTH_METHOD 272 +#define T_FORMATION 273 +#define T_NUM_SYNC 274 +#define T_COORDINATOR 275 +#define T_WORKER 276 +#define T_ASYNC 277 +#define T_NO_MONITOR 278 +#define T_LAUNCH 279 +#define T_DEFERRED 280 +#define T_IMMEDIATE 281 +#define T_INITIALLY 282 +#define T_VOLUME 283 +#define T_LISTEN 284 +#define T_CITUS_SECONDARY 285 +#define T_CANDIDATE_PRIORITY 286 +#define T_PORT 287 +#define T_PASSWORD 288 +#define T_MONITOR_PASSWORD 289 +#define T_CITUS_CLUSTER_NAME 290 +#define T_DEBIAN_CLUSTER 291 +#define T_REPLICATION_QUORUM 292 +#define T_REPLICATION_PASSWORD 293 +#define T_EXTENSION_VERSION 294 +#define T_BIND_SOURCE 295 +#define T_FS_INIT 296 +#define T_FS_SINGLE 297 +#define T_FS_PRIMARY 298 +#define T_FS_WAIT_PRIMARY 299 +#define T_FS_WAIT_STANDBY 300 +#define T_FS_DEMOTED 301 +#define T_FS_DEMOTE_TIMEOUT 302 +#define T_FS_DRAINING 303 +#define T_FS_SECONDARY 304 +#define T_FS_CATCHINGUP 305 +#define T_FS_PREP_PROMOTION 306 +#define T_FS_STOP_REPLICATION 307 +#define T_FS_MAINTENANCE 308 +#define T_FS_JOIN_PRIMARY 309 +#define T_FS_APPLY_SETTINGS 310 +#define T_FS_PREPARE_MAINTENANCE 311 +#define T_FS_WAIT_MAINTENANCE 312 +#define T_FS_REPORT_LSN 313 +#define T_FS_FAST_FORWARD 314 +#define T_FS_JOIN_SECONDARY 315 +#define T_FS_DROPPED 316 +#define T_EXEC 317 +#define T_EXEC_FAILS 318 +#define T_PG_AUTOCTL 319 +#define T_WAIT 320 +#define T_UNTIL 321 +#define T_TIMEOUT 322 +#define T_AND 323 +#define T_IS 324 +#define T_WITH 325 +#define T_ASSERT 326 +#define T_SQL 327 +#define T_EXPECT 328 +#define T_ERROR 329 +#define T_PROMOTE 330 +#define T_NETWORK 331 +#define T_DISCONNECT 332 +#define T_CONNECT 333 +#define T_SLEEP 334 +#define T_COMPOSE 335 +#define T_DOWN 336 +#define T_START 337 +#define T_STOP 338 +#define T_STOPPED 339 +#define T_KILL 340 +#define T_INJECT 341 +#define T_STATE 342 +#define T_ASSIGNED_STATE 343 +#define T_IN 344 +#define T_GROUP 345 +#define T_LBRACE 346 +#define T_RBRACE 347 +#define T_COMMA 348 +#define T_POSTGRES 349 +#define T_STAYS 350 +#define T_WHILE 351 +#define T_THROUGH 352 +#define T_SET 353 +#define T_LOGS 354 +#define T_NOT 355 +#define T_CONTAINS 356 +#define T_MATCHES 357 +#define T_INTEGER 358 +#define T_IDENT 359 +#define T_STRING 360 +#define T_BLOCK 361 +#define T_SHELL_ARGS 362 /* Copy the first part of user declarations. */ @@ -337,8 +325,8 @@ static TestSpec *current_spec = NULL; static void yyerror(const char *msg) { - fprintf(stderr, "pgaftest: parse error at line %d: %s\n", - pgaf_line_number, msg); + fprintf(/* IGNORE-BANNED */ stderr, "pgaftest: parse error at line %d: %s\n", + pgaf_line_number, msg); exit(1); } @@ -450,7 +438,7 @@ expand_tuple_expect(char *buf, int buflen) } if (l > 0) { - memcpy(tmp + pos, row, l); + memcpy(tmp + pos, row, l); /* IGNORE-BANNED */ pos += l; } tmp[pos] = '\0'; @@ -459,7 +447,7 @@ expand_tuple_expect(char *buf, int buflen) if (!first) { - strncpy(buf, tmp, buflen - 1); + strlcpy(buf, tmp, buflen); } } @@ -527,7 +515,7 @@ typedef union YYSTYPE } /* Line 193 of yacc.c. */ -#line 473 "test_spec_parse.c" +#line 461 "test_spec_parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -539,7 +527,7 @@ YYSTYPE; /* Line 216 of yacc.c. */ -#line 486 "test_spec_parse.c" +#line 474 "test_spec_parse.c" #ifdef short # undef short @@ -755,26 +743,26 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 24 +#define YYFINAL 21 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 587 +#define YYLAST 523 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 115 +#define YYNTOKENS 108 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 68 +#define YYNNTS 62 /* YYNRULES -- Number of rules. */ -#define YYNRULES 208 +#define YYNRULES 193 /* YYNRULES -- Number of states. */ -#define YYNSTATES 338 +#define YYNSTATES 312 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 368 +#define YYMAXUTOK 362 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -787,7 +775,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 114, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -818,7 +806,7 @@ static const yytype_uint8 yytranslate[] = 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 + 105, 106, 107 }; #if YYDEBUG @@ -828,121 +816,115 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint16 yyprhs[] = { 0, 0, 3, 5, 8, 10, 12, 14, 16, 18, - 20, 21, 27, 28, 34, 35, 38, 40, 42, 44, - 46, 47, 50, 52, 54, 56, 58, 60, 62, 64, - 66, 70, 74, 78, 82, 87, 92, 99, 102, 105, - 108, 111, 114, 117, 120, 121, 128, 129, 132, 134, - 136, 138, 140, 142, 144, 147, 148, 151, 153, 155, - 156, 157, 162, 163, 171, 172, 175, 177, 179, 181, - 183, 185, 188, 191, 193, 195, 197, 200, 203, 206, - 209, 212, 215, 218, 221, 224, 227, 230, 234, 238, - 241, 244, 248, 252, 253, 256, 258, 260, 262, 264, - 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, - 286, 290, 293, 297, 300, 304, 307, 309, 311, 313, - 318, 323, 325, 329, 330, 333, 335, 337, 341, 345, - 346, 356, 357, 367, 375, 383, 389, 395, 402, 404, - 406, 410, 414, 415, 418, 421, 426, 427, 430, 434, - 441, 448, 455, 462, 466, 470, 473, 476, 480, 484, - 487, 489, 493, 497, 501, 504, 507, 511, 515, 519, - 524, 528, 532, 533, 539, 545, 549, 554, 560, 565, - 571, 576, 581, 586, 589, 590, 593, 595, 597, 599, - 601, 603, 605, 607, 609, 611, 613, 615, 617, 619, - 621, 623, 625, 627, 629, 631, 633, 635, 637 + 19, 25, 26, 29, 31, 33, 35, 37, 39, 41, + 43, 45, 49, 53, 57, 61, 66, 71, 78, 81, + 84, 87, 90, 93, 96, 99, 100, 107, 108, 111, + 113, 115, 117, 119, 121, 123, 126, 127, 130, 132, + 134, 135, 136, 141, 142, 150, 151, 154, 156, 158, + 160, 162, 164, 167, 170, 172, 174, 176, 179, 182, + 185, 188, 191, 194, 197, 200, 203, 206, 209, 213, + 217, 220, 223, 227, 231, 232, 235, 237, 239, 241, + 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, + 265, 268, 272, 275, 279, 282, 284, 286, 288, 293, + 298, 300, 304, 305, 308, 310, 312, 316, 320, 321, + 331, 332, 342, 350, 358, 364, 370, 377, 379, 381, + 385, 389, 390, 393, 396, 401, 402, 405, 409, 416, + 423, 430, 437, 441, 444, 447, 451, 455, 458, 460, + 464, 468, 472, 475, 478, 482, 486, 490, 495, 499, + 503, 504, 510, 516, 520, 525, 531, 536, 542, 545, + 546, 549, 551, 553, 555, 557, 559, 561, 563, 565, + 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, + 587, 589, 591, 593 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 116, 0, -1, 117, -1, 116, 117, -1, 118, -1, - 120, -1, 144, -1, 145, -1, 146, -1, 179, -1, - -1, 3, 92, 119, 124, 93, -1, -1, 4, 92, - 121, 122, 93, -1, -1, 122, 123, -1, 131, -1, - 127, -1, 129, -1, 130, -1, -1, 124, 125, -1, - 126, -1, 127, -1, 129, -1, 130, -1, 128, -1, - 131, -1, 41, -1, 5, -1, 5, 37, 110, -1, - 5, 15, 110, -1, 5, 33, 109, -1, 5, 34, - 111, -1, 5, 110, 25, 26, -1, 5, 110, 28, - 85, -1, 5, 110, 25, 26, 34, 111, -1, 14, - 111, -1, 14, 110, -1, 40, 110, -1, 40, 111, - -1, 16, 110, -1, 17, 110, -1, 18, 110, -1, - -1, 19, 132, 133, 92, 136, 93, -1, -1, 133, - 135, -1, 110, -1, 111, -1, 17, -1, 5, -1, - 6, -1, 134, -1, 20, 109, -1, -1, 136, 139, - -1, 110, -1, 5, -1, -1, -1, 137, 138, 140, - 142, -1, -1, 6, 110, 138, 141, 92, 142, 93, - -1, -1, 142, 143, -1, 21, -1, 22, -1, 23, - -1, 24, -1, 26, -1, 25, 26, -1, 25, 27, - -1, 27, -1, 30, -1, 31, -1, 32, 109, -1, - 91, 109, -1, 33, 109, -1, 36, 110, -1, 37, - 110, -1, 16, 110, -1, 17, 110, -1, 18, 110, - -1, 38, 110, -1, 39, 111, -1, 35, 111, -1, - 29, 110, 110, -1, 29, 110, 111, -1, 9, 147, - -1, 10, 147, -1, 11, 182, 147, -1, 92, 148, - 93, -1, -1, 148, 149, -1, 150, -1, 156, -1, - 163, -1, 164, -1, 165, -1, 166, -1, 168, -1, - 169, -1, 170, -1, 171, -1, 174, -1, 175, -1, - 176, -1, 177, -1, 178, -1, 63, 110, 113, -1, - 63, 110, -1, 64, 110, 113, -1, 64, 110, -1, - 65, 110, 113, -1, 65, 110, -1, 65, -1, 13, - -1, 70, -1, 110, 88, 151, 181, -1, 110, 88, - 151, 110, -1, 152, -1, 153, 69, 152, -1, -1, - 98, 155, -1, 181, -1, 110, -1, 155, 94, 181, - -1, 155, 94, 110, -1, -1, 66, 67, 110, 88, - 151, 181, 157, 154, 162, -1, -1, 66, 67, 110, - 88, 151, 110, 158, 154, 162, -1, 66, 67, 110, - 89, 151, 181, 162, -1, 66, 67, 110, 89, 151, - 110, 162, -1, 66, 67, 110, 85, 162, -1, 66, - 67, 159, 160, 162, -1, 66, 67, 152, 69, 153, - 162, -1, 181, -1, 110, -1, 159, 94, 181, -1, - 159, 94, 110, -1, -1, 90, 161, -1, 91, 109, - -1, 161, 94, 91, 109, -1, -1, 68, 109, -1, - 71, 68, 109, -1, 72, 110, 88, 151, 181, 162, - -1, 72, 110, 88, 151, 110, 162, -1, 72, 110, - 89, 151, 181, 162, -1, 72, 110, 89, 151, 110, - 162, -1, 72, 108, 112, -1, 73, 110, 112, -1, - 74, 112, -1, 74, 75, -1, 74, 75, 110, -1, - 74, 75, 109, -1, 76, 167, -1, 110, -1, 167, - 94, 110, -1, 77, 78, 110, -1, 77, 79, 110, - -1, 80, 109, -1, 81, 82, -1, 81, 83, 110, - -1, 81, 84, 110, -1, 81, 86, 110, -1, 81, - 87, 110, 113, -1, 84, 95, 137, -1, 83, 95, - 137, -1, -1, 97, 173, 92, 148, 93, -1, 72, - 137, 96, 181, 172, -1, 99, 110, 110, -1, 100, - 110, 102, 111, -1, 100, 110, 101, 102, 111, -1, - 100, 110, 103, 111, -1, 100, 110, 101, 103, 111, - -1, 104, 112, 74, 112, -1, 105, 106, 114, 110, - -1, 105, 107, 114, 110, -1, 12, 180, -1, -1, - 180, 182, -1, 42, -1, 43, -1, 44, -1, 45, - -1, 46, -1, 47, -1, 48, -1, 49, -1, 50, - -1, 51, -1, 52, -1, 53, -1, 54, -1, 55, - -1, 56, -1, 57, -1, 58, -1, 59, -1, 60, - -1, 61, -1, 62, -1, 110, -1, 111, -1 + 109, 0, -1, 110, -1, 109, 110, -1, 111, -1, + 133, -1, 134, -1, 135, -1, 166, -1, -1, 3, + 91, 112, 113, 92, -1, -1, 113, 114, -1, 115, + -1, 116, -1, 118, -1, 119, -1, 117, -1, 120, + -1, 40, -1, 4, -1, 4, 36, 104, -1, 4, + 14, 104, -1, 4, 32, 103, -1, 4, 33, 105, + -1, 4, 104, 24, 25, -1, 4, 104, 27, 84, + -1, 4, 104, 24, 25, 33, 105, -1, 13, 105, + -1, 13, 104, -1, 39, 104, -1, 39, 105, -1, + 15, 104, -1, 16, 104, -1, 17, 104, -1, -1, + 18, 121, 122, 91, 125, 92, -1, -1, 122, 124, + -1, 104, -1, 105, -1, 16, -1, 4, -1, 5, + -1, 123, -1, 19, 103, -1, -1, 125, 128, -1, + 104, -1, 4, -1, -1, -1, 126, 127, 129, 131, + -1, -1, 5, 104, 127, 130, 91, 131, 92, -1, + -1, 131, 132, -1, 20, -1, 21, -1, 22, -1, + 23, -1, 25, -1, 24, 25, -1, 24, 26, -1, + 26, -1, 29, -1, 30, -1, 31, 103, -1, 90, + 103, -1, 32, 103, -1, 35, 104, -1, 36, 104, + -1, 15, 104, -1, 16, 104, -1, 17, 104, -1, + 37, 104, -1, 38, 105, -1, 34, 105, -1, 28, + 104, 104, -1, 28, 104, 105, -1, 8, 136, -1, + 9, 136, -1, 10, 169, 136, -1, 91, 137, 92, + -1, -1, 137, 138, -1, 139, -1, 145, -1, 152, + -1, 153, -1, 154, -1, 155, -1, 157, -1, 158, + -1, 159, -1, 160, -1, 163, -1, 164, -1, 165, + -1, 62, 104, 107, -1, 62, 104, -1, 63, 104, + 107, -1, 63, 104, -1, 64, 104, 107, -1, 64, + 104, -1, 64, -1, 12, -1, 69, -1, 104, 87, + 140, 168, -1, 104, 87, 140, 104, -1, 141, -1, + 142, 68, 141, -1, -1, 97, 144, -1, 168, -1, + 104, -1, 144, 93, 168, -1, 144, 93, 104, -1, + -1, 65, 66, 104, 87, 140, 168, 146, 143, 151, + -1, -1, 65, 66, 104, 87, 140, 104, 147, 143, + 151, -1, 65, 66, 104, 88, 140, 168, 151, -1, + 65, 66, 104, 88, 140, 104, 151, -1, 65, 66, + 104, 84, 151, -1, 65, 66, 148, 149, 151, -1, + 65, 66, 141, 68, 142, 151, -1, 168, -1, 104, + -1, 148, 93, 168, -1, 148, 93, 104, -1, -1, + 89, 150, -1, 90, 103, -1, 150, 93, 90, 103, + -1, -1, 67, 103, -1, 70, 67, 103, -1, 71, + 104, 87, 140, 168, 151, -1, 71, 104, 87, 140, + 104, 151, -1, 71, 104, 88, 140, 168, 151, -1, + 71, 104, 88, 140, 104, 151, -1, 72, 104, 106, + -1, 73, 106, -1, 73, 74, -1, 73, 74, 104, + -1, 73, 74, 103, -1, 75, 156, -1, 104, -1, + 156, 93, 104, -1, 76, 77, 104, -1, 76, 78, + 104, -1, 79, 103, -1, 80, 81, -1, 80, 82, + 104, -1, 80, 83, 104, -1, 80, 85, 104, -1, + 80, 86, 104, 107, -1, 83, 94, 126, -1, 82, + 94, 126, -1, -1, 96, 162, 91, 137, 92, -1, + 71, 126, 95, 168, 161, -1, 98, 104, 104, -1, + 99, 104, 101, 105, -1, 99, 104, 100, 101, 105, + -1, 99, 104, 102, 105, -1, 99, 104, 100, 102, + 105, -1, 11, 167, -1, -1, 167, 169, -1, 41, + -1, 42, -1, 43, -1, 44, -1, 45, -1, 46, + -1, 47, -1, 48, -1, 49, -1, 50, -1, 51, + -1, 52, -1, 53, -1, 54, -1, 55, -1, 56, + -1, 57, -1, 58, -1, 59, -1, 60, -1, 61, + -1, 104, -1, 105, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 213, 213, 214, 218, 219, 220, 221, 222, 223, - 236, 235, 259, 258, 270, 272, 276, 277, 278, 279, - 282, 284, 288, 289, 290, 291, 292, 293, 294, 307, - 311, 318, 325, 331, 338, 345, 352, 365, 371, 381, - 387, 397, 407, 413, 424, 423, 440, 442, 451, 452, - 453, 454, 455, 459, 464, 470, 472, 491, 492, 501, - 518, 517, 525, 524, 532, 534, 538, 543, 548, 552, - 556, 560, 564, 568, 572, 576, 580, 584, 588, 592, - 598, 604, 609, 614, 619, 627, 633, 639, 653, 674, - 681, 692, 710, 725, 728, 736, 737, 738, 739, 740, - 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, - 764, 771, 777, 784, 790, 798, 804, 831, 831, 842, - 857, 875, 876, 891, 893, 897, 905, 913, 920, 932, - 931, 943, 942, 953, 962, 971, 978, 992, 1007, 1013, - 1020, 1026, 1039, 1041, 1045, 1050, 1058, 1059, 1060, 1071, - 1079, 1087, 1095, 1103, 1155, 1170, 1177, 1181, 1187, 1200, - 1208, 1216, 1231, 1237, 1250, 1264, 1268, 1274, 1280, 1306, - 1340, 1346, 1363, 1363, 1368, 1387, 1412, 1421, 1430, 1439, - 1460, 1482, 1494, 1513, 1516, 1518, 1540, 1541, 1542, 1543, - 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, - 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1568, 1569 + 0, 211, 211, 212, 216, 217, 218, 219, 220, 233, + 232, 242, 244, 248, 249, 250, 251, 252, 253, 254, + 267, 271, 278, 285, 291, 298, 305, 312, 325, 331, + 341, 347, 357, 367, 373, 384, 383, 400, 402, 411, + 412, 413, 414, 415, 419, 424, 430, 432, 451, 452, + 461, 478, 477, 485, 484, 492, 494, 498, 503, 508, + 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, + 552, 558, 564, 569, 574, 579, 587, 593, 599, 613, + 634, 641, 652, 670, 685, 688, 696, 697, 698, 699, + 700, 701, 702, 703, 704, 705, 706, 707, 708, 722, + 729, 735, 742, 748, 756, 762, 789, 789, 800, 815, + 833, 834, 849, 851, 855, 863, 871, 878, 890, 889, + 901, 900, 911, 920, 929, 936, 950, 965, 971, 978, + 984, 997, 999, 1003, 1008, 1016, 1017, 1018, 1029, 1037, + 1045, 1053, 1071, 1086, 1093, 1097, 1103, 1116, 1124, 1132, + 1147, 1153, 1166, 1180, 1184, 1190, 1196, 1222, 1256, 1262, + 1279, 1279, 1284, 1303, 1328, 1337, 1346, 1355, 1371, 1374, + 1376, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, + 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, + 1417, 1418, 1426, 1427 }; #endif @@ -952,17 +934,17 @@ static const yytype_uint16 yyrline[] = * First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "T_CLUSTER", "T_SCENARIO", "T_MONITOR", - "T_NODE", "T_CITUS_COORDINATOR", "T_CITUS_WORKER", "T_SETUP", - "T_TEARDOWN", "T_STEP", "T_SEQUENCE", "T_EQUALS", "T_IMAGE", - "T_IMAGE_TARGET", "T_SSL", "T_AUTH", "T_AUTH_METHOD", "T_FORMATION", - "T_NUM_SYNC", "T_COORDINATOR", "T_WORKER", "T_ASYNC", "T_NO_MONITOR", - "T_LAUNCH", "T_DEFERRED", "T_IMMEDIATE", "T_INITIALLY", "T_VOLUME", - "T_LISTEN", "T_CITUS_SECONDARY", "T_CANDIDATE_PRIORITY", "T_PORT", - "T_PASSWORD", "T_MONITOR_PASSWORD", "T_CITUS_CLUSTER_NAME", - "T_DEBIAN_CLUSTER", "T_REPLICATION_QUORUM", "T_REPLICATION_PASSWORD", - "T_EXTENSION_VERSION", "T_BIND_SOURCE", "T_FS_INIT", "T_FS_SINGLE", - "T_FS_PRIMARY", "T_FS_WAIT_PRIMARY", "T_FS_WAIT_STANDBY", "T_FS_DEMOTED", + "$end", "error", "$undefined", "T_CLUSTER", "T_MONITOR", "T_NODE", + "T_CITUS_COORDINATOR", "T_CITUS_WORKER", "T_SETUP", "T_TEARDOWN", + "T_STEP", "T_SEQUENCE", "T_EQUALS", "T_IMAGE", "T_IMAGE_TARGET", "T_SSL", + "T_AUTH", "T_AUTH_METHOD", "T_FORMATION", "T_NUM_SYNC", "T_COORDINATOR", + "T_WORKER", "T_ASYNC", "T_NO_MONITOR", "T_LAUNCH", "T_DEFERRED", + "T_IMMEDIATE", "T_INITIALLY", "T_VOLUME", "T_LISTEN", + "T_CITUS_SECONDARY", "T_CANDIDATE_PRIORITY", "T_PORT", "T_PASSWORD", + "T_MONITOR_PASSWORD", "T_CITUS_CLUSTER_NAME", "T_DEBIAN_CLUSTER", + "T_REPLICATION_QUORUM", "T_REPLICATION_PASSWORD", "T_EXTENSION_VERSION", + "T_BIND_SOURCE", "T_FS_INIT", "T_FS_SINGLE", "T_FS_PRIMARY", + "T_FS_WAIT_PRIMARY", "T_FS_WAIT_STANDBY", "T_FS_DEMOTED", "T_FS_DEMOTE_TIMEOUT", "T_FS_DRAINING", "T_FS_SECONDARY", "T_FS_CATCHINGUP", "T_FS_PREP_PROMOTION", "T_FS_STOP_REPLICATION", "T_FS_MAINTENANCE", "T_FS_JOIN_PRIMARY", "T_FS_APPLY_SETTINGS", @@ -974,23 +956,20 @@ static const char *const yytname[] = "T_COMPOSE", "T_DOWN", "T_START", "T_STOP", "T_STOPPED", "T_KILL", "T_INJECT", "T_STATE", "T_ASSIGNED_STATE", "T_IN", "T_GROUP", "T_LBRACE", "T_RBRACE", "T_COMMA", "T_POSTGRES", "T_STAYS", "T_WHILE", "T_THROUGH", - "T_SET", "T_LOGS", "T_NOT", "T_CONTAINS", "T_MATCHES", "T_NODE_ACTIVE", - "T_MARK", "T_HEALTHY", "T_UNHEALTHY", "T_STATES", "T_INTEGER", "T_IDENT", - "T_STRING", "T_BLOCK", "T_SHELL_ARGS", "':'", "$accept", "spec", - "spec_item", "cluster_block", "@1", "scenario_block", "@2", - "scenario_item_list", "scenario_item", "cluster_item_list", - "cluster_item", "monitor_line", "image_line", "extension_version_line", - "ssl_line", "auth_line", "formation_block", "@3", "formation_opt_list", - "bare_name", "formation_opt", "node_list", "node_name", "init_node_slot", - "node_line", "@4", "@5", "node_opt_list", "node_opt", "setup_block", - "teardown_block", "named_step", "cmd_block", "cmd_list", "step_cmd", - "exec_cmd", "state_op", "wait_multi_condition", - "wait_multi_condition_list", "opt_passing_through", "pass_state_list", - "wait_cmd", "@6", "@7", "state_name_list", "opt_in_group", "group_items", - "opt_timeout", "assert_cmd", "sql_cmd", "expect_cmd", "promote_cmd", - "promote_list", "network_cmd", "sleep_cmd", "compose_cmd", - "postgres_ctl_cmd", "while_body", "@8", "stays_while_cmd", - "set_monitor_cmd", "logs_cmd", "node_active_cmd", "mark_health_cmd", + "T_SET", "T_LOGS", "T_NOT", "T_CONTAINS", "T_MATCHES", "T_INTEGER", + "T_IDENT", "T_STRING", "T_BLOCK", "T_SHELL_ARGS", "$accept", "spec", + "spec_item", "cluster_block", "@1", "cluster_item_list", "cluster_item", + "monitor_line", "image_line", "extension_version_line", "ssl_line", + "auth_line", "formation_block", "@2", "formation_opt_list", "bare_name", + "formation_opt", "node_list", "node_name", "init_node_slot", "node_line", + "@3", "@4", "node_opt_list", "node_opt", "setup_block", "teardown_block", + "named_step", "cmd_block", "cmd_list", "step_cmd", "exec_cmd", + "state_op", "wait_multi_condition", "wait_multi_condition_list", + "opt_passing_through", "pass_state_list", "wait_cmd", "@5", "@6", + "state_name_list", "opt_in_group", "group_items", "opt_timeout", + "assert_cmd", "sql_cmd", "expect_cmd", "promote_cmd", "promote_list", + "network_cmd", "sleep_cmd", "compose_cmd", "postgres_ctl_cmd", + "while_body", "@7", "stays_while_cmd", "set_monitor_cmd", "logs_cmd", "sequence_block", "sequence_names", "fsm_state", "ident_or_string", 0 }; #endif @@ -1011,61 +990,58 @@ static const yytype_uint16 yytoknum[] = 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 58 + 355, 356, 357, 358, 359, 360, 361, 362 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 115, 116, 116, 117, 117, 117, 117, 117, 117, - 119, 118, 121, 120, 122, 122, 123, 123, 123, 123, - 124, 124, 125, 125, 125, 125, 125, 125, 125, 126, - 126, 126, 126, 126, 126, 126, 126, 127, 127, 128, - 128, 129, 130, 130, 132, 131, 133, 133, 134, 134, - 134, 134, 134, 135, 135, 136, 136, 137, 137, 138, - 140, 139, 141, 139, 142, 142, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 144, - 145, 146, 147, 148, 148, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 150, 150, 150, 150, 150, 150, 150, 151, 151, 152, - 152, 153, 153, 154, 154, 155, 155, 155, 155, 157, - 156, 158, 156, 156, 156, 156, 156, 156, 159, 159, - 159, 159, 160, 160, 161, 161, 162, 162, 162, 163, - 163, 163, 163, 163, 164, 165, 165, 165, 165, 166, - 167, 167, 168, 168, 169, 170, 170, 170, 170, 170, - 171, 171, 173, 172, 174, 175, 176, 176, 176, 176, - 177, 178, 178, 179, 180, 180, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 182, 182 + 0, 108, 109, 109, 110, 110, 110, 110, 110, 112, + 111, 113, 113, 114, 114, 114, 114, 114, 114, 114, + 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, + 117, 117, 118, 119, 119, 121, 120, 122, 122, 123, + 123, 123, 123, 123, 124, 124, 125, 125, 126, 126, + 127, 129, 128, 130, 128, 131, 131, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 133, 134, 135, 136, 137, 137, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, + 139, 139, 139, 139, 139, 139, 140, 140, 141, 141, + 142, 142, 143, 143, 144, 144, 144, 144, 146, 145, + 147, 145, 145, 145, 145, 145, 145, 148, 148, 148, + 148, 149, 149, 150, 150, 151, 151, 151, 152, 152, + 152, 152, 153, 154, 154, 154, 154, 155, 156, 156, + 157, 157, 158, 159, 159, 159, 159, 159, 160, 160, + 162, 161, 163, 164, 165, 165, 165, 165, 166, 167, + 167, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 169, 169 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, - 0, 5, 0, 5, 0, 2, 1, 1, 1, 1, - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 3, 3, 3, 4, 4, 6, 2, 2, 2, - 2, 2, 2, 2, 0, 6, 0, 2, 1, 1, - 1, 1, 1, 1, 2, 0, 2, 1, 1, 0, - 0, 4, 0, 7, 0, 2, 1, 1, 1, 1, - 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, - 2, 3, 3, 0, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 2, 3, 2, 3, 2, 1, 1, 1, 4, - 4, 1, 3, 0, 2, 1, 1, 3, 3, 0, - 9, 0, 9, 7, 7, 5, 5, 6, 1, 1, - 3, 3, 0, 2, 2, 4, 0, 2, 3, 6, - 6, 6, 6, 3, 3, 2, 2, 3, 3, 2, - 1, 3, 3, 3, 2, 2, 3, 3, 3, 4, - 3, 3, 0, 5, 5, 3, 4, 5, 4, 5, - 4, 4, 4, 2, 0, 2, 1, 1, 1, 1, + 0, 2, 1, 2, 1, 1, 1, 1, 1, 0, + 5, 0, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 4, 4, 6, 2, 2, + 2, 2, 2, 2, 2, 0, 6, 0, 2, 1, + 1, 1, 1, 1, 1, 2, 0, 2, 1, 1, + 0, 0, 4, 0, 7, 0, 2, 1, 1, 1, + 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, + 2, 2, 3, 3, 0, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 2, 3, 2, 3, 2, 1, 1, 1, 4, 4, + 1, 3, 0, 2, 1, 1, 3, 3, 0, 9, + 0, 9, 7, 7, 5, 5, 6, 1, 1, 3, + 3, 0, 2, 2, 4, 0, 2, 3, 6, 6, + 6, 6, 3, 2, 2, 3, 3, 2, 1, 3, + 3, 3, 2, 2, 3, 3, 3, 4, 3, 3, + 0, 5, 5, 3, 4, 5, 4, 5, 2, 0, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1073,276 +1049,258 @@ static const yytype_uint8 yyr2[] = * means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 0, 0, 184, 0, 2, 4, - 5, 6, 7, 8, 9, 10, 12, 93, 89, 90, - 207, 208, 0, 183, 1, 3, 20, 14, 0, 91, - 185, 0, 0, 0, 0, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, - 0, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 29, 0, 0, - 0, 0, 44, 0, 28, 11, 21, 22, 23, 26, - 24, 25, 27, 13, 15, 17, 18, 19, 16, 111, - 113, 115, 0, 58, 0, 57, 0, 0, 156, 155, - 160, 159, 0, 0, 164, 165, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 169, 0, 2, 4, 5, + 6, 7, 8, 9, 84, 80, 81, 192, 193, 0, + 168, 1, 3, 11, 0, 82, 170, 0, 0, 0, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 83, 0, 0, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 20, 0, + 0, 0, 0, 35, 0, 19, 10, 12, 13, 14, + 17, 15, 16, 18, 100, 102, 104, 0, 49, 48, + 0, 0, 144, 143, 148, 147, 0, 0, 152, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 38, 37, 41, 42, 43, 46, 39, 40, - 110, 112, 114, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 139, 0, 142, 138, 153, 0, - 0, 0, 154, 158, 157, 0, 162, 163, 166, 167, - 168, 0, 57, 171, 170, 175, 0, 0, 0, 0, - 0, 0, 31, 32, 33, 30, 0, 0, 0, 146, - 0, 0, 0, 0, 0, 146, 117, 118, 0, 0, - 0, 161, 169, 0, 0, 176, 178, 180, 181, 182, - 34, 35, 51, 52, 50, 0, 55, 48, 49, 53, - 47, 0, 0, 135, 0, 0, 0, 121, 146, 0, - 143, 141, 140, 136, 146, 146, 146, 146, 172, 174, - 177, 179, 0, 54, 0, 147, 0, 131, 129, 146, - 146, 0, 0, 137, 144, 0, 150, 149, 152, 151, - 0, 36, 0, 45, 59, 56, 148, 123, 123, 134, - 133, 0, 122, 0, 93, 59, 60, 0, 146, 146, - 120, 119, 145, 0, 62, 64, 126, 124, 125, 132, - 130, 173, 0, 61, 0, 64, 0, 0, 0, 66, - 67, 68, 69, 0, 70, 73, 0, 74, 75, 0, - 0, 0, 0, 0, 0, 0, 0, 65, 128, 127, - 0, 81, 82, 83, 71, 72, 0, 76, 78, 86, - 79, 80, 84, 85, 77, 63, 87, 88 + 0, 0, 0, 29, 28, 32, 33, 34, 37, 30, + 31, 99, 101, 103, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 128, 0, 131, 127, 0, + 0, 0, 142, 146, 145, 0, 150, 151, 154, 155, + 156, 0, 48, 159, 158, 163, 0, 0, 0, 22, + 23, 24, 21, 0, 0, 0, 135, 0, 0, 0, + 0, 0, 135, 106, 107, 0, 0, 0, 149, 157, + 0, 0, 164, 166, 25, 26, 42, 43, 41, 0, + 46, 39, 40, 44, 38, 0, 0, 124, 0, 0, + 0, 110, 135, 0, 132, 130, 129, 125, 135, 135, + 135, 135, 160, 162, 165, 167, 0, 45, 0, 136, + 0, 120, 118, 135, 135, 0, 0, 126, 133, 0, + 139, 138, 141, 140, 0, 27, 0, 36, 50, 47, + 137, 112, 112, 123, 122, 0, 111, 0, 84, 50, + 51, 0, 135, 135, 109, 108, 134, 0, 53, 55, + 115, 113, 114, 121, 119, 161, 0, 52, 0, 55, + 0, 0, 0, 57, 58, 59, 60, 0, 61, 64, + 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 117, 116, 0, 72, 73, 74, 62, 63, + 0, 67, 69, 77, 70, 71, 75, 76, 68, 54, + 78, 79 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 7, 8, 9, 26, 10, 27, 32, 84, 31, - 76, 77, 78, 79, 80, 81, 82, 127, 188, 219, - 220, 244, 96, 276, 265, 285, 292, 293, 317, 11, - 12, 13, 18, 28, 51, 52, 198, 155, 228, 278, - 287, 53, 268, 267, 156, 195, 230, 223, 54, 55, - 56, 57, 101, 58, 59, 60, 61, 239, 260, 62, - 63, 64, 65, 66, 14, 23, 157, 22 + -1, 6, 7, 8, 23, 27, 67, 68, 69, 70, + 71, 72, 73, 108, 165, 193, 194, 218, 80, 250, + 239, 259, 266, 267, 291, 9, 10, 11, 15, 24, + 44, 45, 175, 136, 202, 252, 261, 46, 242, 241, + 137, 172, 204, 197, 47, 48, 49, 50, 85, 51, + 52, 53, 54, 213, 234, 55, 56, 57, 12, 20, + 138, 19 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing * STATE-NUM. */ -#define YYPACT_NINF -180 +#define YYPACT_NINF -160 static const yytype_int16 yypact[] = { - 69, -65, -41, -29, -29, -74, -180, 50, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -29, -74, -180, -180, -180, -180, 414, -180, - -180, 5, 14, -28, -9, 20, 2, 3, 39, -64, - 57, -3, -23, 1, 28, 78, -180, 90, 91, 31, - -1, -180, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -8, 6, 92, - 93, 94, -180, 9, -180, -180, -180, -180, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -180, -180, 118, - 119, 120, 137, -180, 95, 33, -7, 122, 15, -180, - -180, 10, 125, 126, -180, -180, 127, 128, 129, 130, - 4, 4, 131, -6, 41, 132, 155, 133, 96, 134, - 160, 13, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -180, -180, -21, 173, -77, -180, -180, 7, - 7, 525, -180, -180, -180, 161, -180, -180, -180, -180, - -180, 159, -180, -180, -180, -180, 24, 162, 163, 164, - 165, 189, -180, -180, -180, -180, 218, 215, -2, -24, - 7, 7, 191, 211, 167, -24, -180, -180, 206, 236, - 207, -180, -180, 192, 194, -180, -180, -180, -180, -180, - 272, -180, -180, -180, -180, 198, -180, -180, -180, -180, - -180, 199, 241, -180, 275, 305, 222, -180, 23, 202, - 219, -180, -180, -180, -24, -24, -24, -24, -180, -180, - -180, -180, 201, -180, 0, -180, 205, 246, 269, -24, - -24, 7, 191, -180, -180, 248, -180, -180, -180, -180, - 249, -180, 230, -180, -180, -180, -180, 244, 244, -180, - -180, 344, -180, 234, -180, -180, -180, 374, -24, -24, - -180, -180, -180, 461, -180, -180, -180, 250, -180, -180, - -180, -180, 253, 139, 413, -180, 258, 259, 260, -180, - -180, -180, -180, 102, -180, -180, 261, -180, -180, 263, - 264, 265, 267, 268, 270, 271, 266, -180, -180, -180, - 115, -180, -180, -180, -180, -180, 48, -180, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -180 + 45, -76, -65, -65, -45, -160, 109, -160, -160, -160, + -160, -160, -160, -160, -160, -160, -160, -160, -160, -65, + -45, -160, -160, -160, 145, -160, -160, 6, -72, -64, + -57, -24, 3, -25, -62, -19, 24, -14, 47, 19, + 32, -160, -9, 27, -160, -160, -160, -160, -160, -160, + -160, -160, -160, -160, -160, -160, -160, -160, -5, 11, + 33, 53, 111, -160, 30, -160, -160, -160, -160, -160, + -160, -160, -160, -160, 106, 112, 126, 122, -160, 55, + 29, 128, 102, -160, -160, 58, 127, 131, -160, -160, + 132, 134, 135, 136, 4, 4, 137, 21, 138, 129, + 140, 142, 73, -160, -160, -160, -160, -160, -160, -160, + -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, + -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, + -160, -160, -160, -160, -160, -51, 244, -75, -160, 17, + 17, 440, -160, -160, -160, 213, -160, -160, -160, -160, + -160, 211, -160, -160, -160, -160, 110, 214, 215, -160, + -160, -160, -160, 296, 241, 1, 44, 17, 17, 224, + 239, 143, 44, -160, -160, 207, 228, 240, -160, -160, + 230, 232, -160, -160, 305, -160, -160, -160, -160, 236, + -160, -160, -160, -160, -160, 237, 274, -160, 249, 313, + 255, -160, 20, 242, 253, -160, -160, -160, 44, 44, + 44, 44, -160, -160, -160, -160, 243, -160, -1, -160, + 248, 276, 279, 44, 44, 17, 224, -160, -160, 262, + -160, -160, -160, -160, 327, -160, 315, -160, -160, -160, + -160, 323, 323, -160, -160, 334, -160, 318, -160, -160, + -160, 355, 44, 44, -160, -160, -160, 251, -160, -160, + -160, 329, -160, -160, -160, -160, 332, 124, 419, -160, + 320, 321, 322, -160, -160, -160, -160, 197, -160, -160, + 324, -160, -160, 326, 328, 325, 330, 331, 333, 335, + 336, -160, -160, -160, 46, -160, -160, -160, -160, -160, + 125, -160, -160, -160, -160, -160, -160, -160, -160, -160, + -160, -160 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -180, -180, 367, -180, -180, -180, -180, -180, -180, -180, - -180, -180, 347, -180, 349, 351, 352, -180, -180, -180, - -180, -180, -110, 135, -180, -180, -180, 112, -180, -180, - -180, -180, 30, 138, -180, -180, -148, -178, -180, 140, - -180, -180, -180, -180, -180, -180, -180, -179, -180, -180, - -180, -180, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -180, -180, -180, -180, -159, 386 + -160, -160, 421, -160, -160, -160, -160, -160, -160, -160, + -160, -160, -160, -160, -160, -160, -160, -160, -93, 183, + -160, -160, -160, 164, -160, -160, -160, -160, 22, 188, + -160, -160, -129, -153, -160, 199, -160, -160, -160, -160, + -160, -160, -160, -159, -160, -160, -160, -160, -160, -160, + -160, -160, -160, -160, -160, -160, -160, -160, -160, -160, + -141, 422 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If * positive, shift that token. If negative, reduce the rule which * number is the opposite. If zero, do what YYDEFACT says. * If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -121 +#define YYTABLE_NINF -110 static const yytype_int16 yytable[] = { - 173, 174, 200, 212, 213, 93, 262, 117, 93, 93, - 67, 98, 199, 193, 227, 214, 233, 194, 215, 68, - 196, 69, 70, 71, 72, 118, 119, 15, 68, 120, - 69, 70, 71, 72, 19, 232, 20, 21, 186, 235, - 237, 187, 224, 225, 221, 73, 74, 222, 99, 253, - 24, 16, 29, 1, 2, 256, 257, 258, 259, 3, - 4, 5, 6, 17, 189, 248, 250, 190, 191, 92, - 269, 270, 1, 2, 272, 102, 103, 197, 3, 4, - 5, 6, 89, 105, 106, 107, 104, 108, 109, 161, - 216, 221, 252, 263, 222, 176, 177, 178, 75, 289, - 290, 90, 121, 271, 165, 115, 116, 83, 217, 218, - 172, 94, 281, 95, 172, 179, 122, 123, 288, 128, - 129, 159, 160, 110, 163, 164, 203, 204, 324, 325, - 91, 296, 297, 298, 264, 319, 299, 300, 301, 302, - 303, 304, 305, 114, 306, 307, 308, 309, 310, 97, - 311, 312, 313, 314, 315, 296, 297, 298, 336, 337, - 299, 300, 301, 302, 303, 304, 305, 100, 306, 307, - 308, 309, 310, 111, 311, 312, 313, 314, 315, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 112, 113, 124, 125, 126, 183, 316, 158, 335, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 316, 130, 131, 132, 162, 166, 167, 168, 169, 170, - 171, 175, 192, 182, 210, 184, 180, 154, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 181, - 185, 201, 202, 205, 206, 208, 207, 231, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 209, - 211, 226, 229, 240, 238, 241, 242, 243, 245, 246, - 251, 254, 261, 255, 266, -120, 234, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, -119, 273, - 275, 274, 277, 282, 294, 295, 236, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 321, 322, - 323, 326, 327, 328, 25, 334, 329, 330, 331, 85, - 332, 86, 333, 87, 88, 247, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 320, 279, 30, - 284, 0, 283, 0, 0, 249, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 0, 0, 0, + 177, 153, 154, 78, 236, 186, 187, 78, 78, 98, + 58, 176, 82, 207, 170, 13, 201, 188, 171, 59, + 189, 60, 61, 62, 63, 16, 14, 99, 100, 173, + 206, 101, 74, 166, 209, 211, 167, 168, 198, 199, + 75, 25, 77, 227, 83, 64, 65, 76, 1, 230, + 231, 232, 233, 2, 3, 4, 5, 222, 224, 17, + 18, 270, 271, 272, 243, 244, 273, 274, 275, 276, + 277, 278, 279, 246, 280, 281, 282, 283, 284, 81, + 285, 286, 287, 288, 289, 84, 174, 195, 226, 88, + 196, 237, 190, 263, 264, 96, 245, 163, 66, 102, + 164, 86, 87, 152, 255, 191, 192, 79, 152, 21, + 262, 195, 1, 94, 196, 103, 104, 2, 3, 4, + 5, 156, 157, 158, 141, 238, 95, 293, 89, 90, + 91, 97, 92, 93, 109, 110, 290, 105, 309, 270, + 271, 272, 139, 140, 273, 274, 275, 276, 277, 278, + 279, 145, 280, 281, 282, 283, 284, 106, 285, 286, + 287, 288, 289, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 143, 144, 28, 29, 30, + 31, 180, 181, 111, 290, 107, 32, 33, 34, 112, + 35, 36, 298, 299, 37, 38, 135, 39, 40, 310, + 311, 146, 160, 113, 142, 147, 148, 41, 149, 150, + 151, 155, 159, 42, 43, 161, 162, 205, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 208, 169, 28, 29, 30, 31, 178, 179, 182, + 183, 184, 32, 33, 34, 185, 35, 36, 200, 203, + 37, 38, 210, 39, 40, 214, 212, 215, 216, 217, + 219, 220, 225, 265, -109, 228, 229, -108, 235, 42, + 43, 240, 247, 221, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 223, 248, 249, + 251, 256, 268, 269, 295, 296, 297, 22, 300, 301, + 303, 302, 258, 294, 304, 305, 257, 306, 254, 308, + 307, 253, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 280, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 0, 33, 34, 35, - 36, 0, 0, 0, 286, 0, 37, 38, 39, 0, - 40, 41, 0, 0, 42, 43, 0, 44, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, - 0, 0, 0, 47, 48, 0, 0, 0, 49, 50, - 0, 0, 0, 318, 33, 34, 35, 36, 0, 0, - 0, 0, 0, 37, 38, 39, 0, 40, 41, 0, - 0, 42, 43, 0, 44, 45, 0, 0, 0, 0, - 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, - 47, 48, 0, 0, 0, 49, 50, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153 + 0, 0, 0, 292 }; static const yytype_int16 yycheck[] = { - 110, 111, 161, 5, 6, 5, 6, 15, 5, 5, - 5, 75, 160, 90, 192, 17, 195, 94, 20, 14, - 13, 16, 17, 18, 19, 33, 34, 92, 14, 37, - 16, 17, 18, 19, 4, 194, 110, 111, 25, 198, - 199, 28, 190, 191, 68, 40, 41, 71, 112, 228, - 0, 92, 22, 3, 4, 234, 235, 236, 237, 9, - 10, 11, 12, 92, 85, 224, 225, 88, 89, 67, - 249, 250, 3, 4, 252, 78, 79, 70, 9, 10, - 11, 12, 110, 82, 83, 84, 109, 86, 87, 96, - 92, 68, 69, 93, 71, 101, 102, 103, 93, 278, - 279, 110, 110, 251, 94, 106, 107, 93, 110, 111, - 110, 108, 271, 110, 110, 74, 110, 111, 277, 110, - 111, 88, 89, 95, 109, 110, 102, 103, 26, 27, - 110, 16, 17, 18, 244, 294, 21, 22, 23, 24, - 25, 26, 27, 112, 29, 30, 31, 32, 33, 110, - 35, 36, 37, 38, 39, 16, 17, 18, 110, 111, - 21, 22, 23, 24, 25, 26, 27, 110, 29, 30, - 31, 32, 33, 95, 35, 36, 37, 38, 39, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 110, 110, 110, 110, 110, 109, 91, 112, 93, 42, + 141, 94, 95, 4, 5, 4, 5, 4, 4, 14, + 4, 140, 74, 172, 89, 91, 169, 16, 93, 13, + 19, 15, 16, 17, 18, 3, 91, 32, 33, 12, + 171, 36, 104, 84, 175, 176, 87, 88, 167, 168, + 104, 19, 66, 202, 106, 39, 40, 104, 3, 208, + 209, 210, 211, 8, 9, 10, 11, 198, 199, 104, + 105, 15, 16, 17, 223, 224, 20, 21, 22, 23, + 24, 25, 26, 226, 28, 29, 30, 31, 32, 104, + 34, 35, 36, 37, 38, 104, 69, 67, 68, 103, + 70, 92, 91, 252, 253, 104, 225, 24, 92, 104, + 27, 77, 78, 104, 245, 104, 105, 104, 104, 0, + 251, 67, 3, 94, 70, 104, 105, 8, 9, 10, + 11, 100, 101, 102, 95, 218, 94, 268, 81, 82, + 83, 104, 85, 86, 104, 105, 90, 104, 92, 15, + 16, 17, 87, 88, 20, 21, 22, 23, 24, 25, + 26, 93, 28, 29, 30, 31, 32, 104, 34, 35, + 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 103, 104, 62, 63, 64, + 65, 101, 102, 107, 90, 104, 71, 72, 73, 107, + 75, 76, 25, 26, 79, 80, 104, 82, 83, 104, + 105, 104, 103, 107, 106, 104, 104, 92, 104, 104, + 104, 104, 104, 98, 99, 105, 104, 104, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 91, 113, 113, 113, 112, 110, 110, 110, 110, 110, - 110, 110, 69, 110, 26, 111, 114, 110, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 114, - 110, 110, 113, 111, 111, 110, 112, 110, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 110, - 85, 110, 91, 111, 97, 111, 34, 109, 109, 68, - 88, 109, 111, 94, 109, 69, 110, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 69, 91, - 110, 92, 98, 109, 94, 92, 110, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 110, 110, - 110, 110, 109, 109, 7, 109, 111, 110, 110, 32, - 110, 32, 111, 32, 32, 110, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 295, 268, 23, - 275, -1, 274, -1, -1, 110, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 110, 42, 43, 44, 45, 46, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 104, 68, 62, 63, 64, 65, 104, 107, 105, + 105, 25, 71, 72, 73, 84, 75, 76, 104, 90, + 79, 80, 104, 82, 83, 105, 96, 105, 33, 103, + 103, 67, 87, 92, 68, 103, 93, 68, 105, 98, + 99, 103, 90, 104, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, -1, 63, 64, 65, - 66, -1, -1, -1, 110, -1, 72, 73, 74, -1, - 76, 77, -1, -1, 80, 81, -1, 83, 84, -1, - -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, - -1, -1, -1, 99, 100, -1, -1, -1, 104, 105, - -1, -1, -1, 110, 63, 64, 65, 66, -1, -1, - -1, -1, -1, 72, 73, 74, -1, 76, 77, -1, - -1, 80, 81, -1, 83, 84, -1, -1, -1, -1, - -1, -1, -1, -1, 93, -1, -1, -1, -1, -1, - 99, 100, -1, -1, -1, 104, 105, 42, 43, 44, + 57, 58, 59, 60, 61, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62 + 55, 56, 57, 58, 59, 60, 61, 104, 91, 104, + 97, 103, 93, 91, 104, 104, 104, 6, 104, 103, + 105, 103, 249, 269, 104, 104, 248, 104, 104, 103, + 105, 242, 20, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 104 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing * symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 9, 10, 11, 12, 116, 117, 118, - 120, 144, 145, 146, 179, 92, 92, 92, 147, 147, - 110, 111, 182, 180, 0, 117, 119, 121, 148, 147, - 182, 124, 122, 63, 64, 65, 66, 72, 73, 74, - 76, 77, 80, 81, 83, 84, 93, 99, 100, 104, - 105, 149, 150, 156, 163, 164, 165, 166, 168, 169, - 170, 171, 174, 175, 176, 177, 178, 5, 14, 16, - 17, 18, 19, 40, 41, 93, 125, 126, 127, 128, - 129, 130, 131, 93, 123, 127, 129, 130, 131, 110, - 110, 110, 67, 5, 108, 110, 137, 110, 75, 112, - 110, 167, 78, 79, 109, 82, 83, 84, 86, 87, - 95, 95, 110, 110, 112, 106, 107, 15, 33, 34, - 37, 110, 110, 111, 110, 110, 110, 132, 110, 111, - 113, 113, 113, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 110, 152, 159, 181, 112, 88, - 89, 96, 112, 109, 110, 94, 110, 110, 110, 110, - 110, 110, 110, 137, 137, 110, 101, 102, 103, 74, - 114, 114, 110, 109, 111, 110, 25, 28, 133, 85, - 88, 89, 69, 90, 94, 160, 13, 70, 151, 151, - 181, 110, 113, 102, 103, 111, 111, 112, 110, 110, - 26, 85, 5, 6, 17, 20, 92, 110, 111, 134, - 135, 68, 71, 162, 151, 151, 110, 152, 153, 91, - 161, 110, 181, 162, 110, 181, 110, 181, 97, 172, - 111, 111, 34, 109, 136, 109, 68, 110, 181, 110, - 181, 88, 69, 162, 109, 94, 162, 162, 162, 162, - 173, 111, 6, 93, 137, 139, 109, 158, 157, 162, - 162, 151, 152, 91, 92, 110, 138, 98, 154, 154, - 110, 181, 109, 148, 138, 140, 110, 155, 181, 162, - 162, 93, 141, 142, 94, 92, 16, 17, 18, 21, - 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, - 33, 35, 36, 37, 38, 39, 91, 143, 110, 181, - 142, 110, 110, 110, 26, 27, 110, 109, 109, 111, - 110, 110, 110, 111, 109, 93, 110, 111 + 0, 3, 8, 9, 10, 11, 109, 110, 111, 133, + 134, 135, 166, 91, 91, 136, 136, 104, 105, 169, + 167, 0, 110, 112, 137, 136, 169, 113, 62, 63, + 64, 65, 71, 72, 73, 75, 76, 79, 80, 82, + 83, 92, 98, 99, 138, 139, 145, 152, 153, 154, + 155, 157, 158, 159, 160, 163, 164, 165, 4, 13, + 15, 16, 17, 18, 39, 40, 92, 114, 115, 116, + 117, 118, 119, 120, 104, 104, 104, 66, 4, 104, + 126, 104, 74, 106, 104, 156, 77, 78, 103, 81, + 82, 83, 85, 86, 94, 94, 104, 104, 14, 32, + 33, 36, 104, 104, 105, 104, 104, 104, 121, 104, + 105, 107, 107, 107, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 104, 141, 148, 168, 87, + 88, 95, 106, 103, 104, 93, 104, 104, 104, 104, + 104, 104, 104, 126, 126, 104, 100, 101, 102, 104, + 103, 105, 104, 24, 27, 122, 84, 87, 88, 68, + 89, 93, 149, 12, 69, 140, 140, 168, 104, 107, + 101, 102, 105, 105, 25, 84, 4, 5, 16, 19, + 91, 104, 105, 123, 124, 67, 70, 151, 140, 140, + 104, 141, 142, 90, 150, 104, 168, 151, 104, 168, + 104, 168, 96, 161, 105, 105, 33, 103, 125, 103, + 67, 104, 168, 104, 168, 87, 68, 151, 103, 93, + 151, 151, 151, 151, 162, 105, 5, 92, 126, 128, + 103, 147, 146, 151, 151, 140, 141, 90, 91, 104, + 127, 97, 143, 143, 104, 168, 103, 137, 127, 129, + 104, 144, 168, 151, 151, 92, 130, 131, 93, 91, + 15, 16, 17, 20, 21, 22, 23, 24, 25, 26, + 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, + 90, 132, 104, 168, 131, 104, 104, 104, 25, 26, + 104, 103, 103, 105, 104, 104, 104, 105, 103, 92, + 104, 105 }; #define yyerrok (yyerrstatus = 0) @@ -1418,9 +1376,9 @@ static const yytype_uint8 yystos[] = #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ - fprintf(File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) + fprintf(/* IGNORE-BANNED */ File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif @@ -1577,11 +1535,11 @@ int yyrule; /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf(stderr, " $%d = ", yyi + 1); + fprintf(stderr, " $%d = ", yyi + 1); /* IGNORE-BANNED */ yy_symbol_print(stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); /* IGNORE-BANNED */ } } @@ -1722,11 +1680,13 @@ yytnamerr(char *yyres, const char *yystr) } case '"': + { if (yyres) { yyres[yyn] = '\0'; } return yyn; + } } } do_not_strip_quotes:; @@ -2221,105 +2181,93 @@ yyparse() YY_REDUCE_PRINT(yyn); switch (yyn) { - case 10: -#line 236 "test_spec_parse.y" - { - strlcpy(current_spec->cluster.ssl, "self-signed", - sizeof(current_spec->cluster.ssl)); - strlcpy(current_spec->cluster.auth, "trust", - sizeof(current_spec->cluster.auth)); - } - break; - - case 12: -#line 259 "test_spec_parse.y" + case 9: +#line 233 "test_spec_parse.y" { - current_spec->cluster.monitorApiOnly = true; - current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.ssl, "self-signed", sizeof(current_spec->cluster.ssl)); strlcpy(current_spec->cluster.auth, "trust", sizeof(current_spec->cluster.auth)); + break; } - break; - case 28: -#line 294 "test_spec_parse.y" + case 19: +#line 254 "test_spec_parse.y" { current_spec->cluster.bindSource = true; + break; } - break; - case 29: -#line 308 "test_spec_parse.y" + case 20: +#line 268 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; + break; } - break; - case 30: -#line 312 "test_spec_parse.y" + case 21: +#line 272 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorDebianCluster, (yyvsp[(3) - (3)].str), sizeof(current_spec->cluster.monitorDebianCluster)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 31: -#line 319 "test_spec_parse.y" + case 22: +#line 279 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorImageTarget, (yyvsp[(3) - (3)].str), sizeof(current_spec->cluster.monitorImageTarget)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 32: -#line 326 "test_spec_parse.y" + case 23: +#line 286 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; /* monitor port not stored in TestCluster yet; ignore */ (void) (yyvsp[(3) - (3)].ival); + break; } - break; - case 33: -#line 332 "test_spec_parse.y" + case 24: +#line 292 "test_spec_parse.y" { current_spec->cluster.withMonitor = true; strlcpy(current_spec->cluster.monitorPassword, (yyvsp[(3) - (3)].str), sizeof(current_spec->cluster.monitorPassword)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 34: -#line 339 "test_spec_parse.y" + case 25: +#line 299 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (4)].str), sizeof(current_spec->cluster.secondMonitorName)); current_spec->cluster.secondMonitorStopped = true; free((yyvsp[(2) - (4)].str)); + break; } - break; - case 35: -#line 346 "test_spec_parse.y" + case 26: +#line 306 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (4)].str), sizeof(current_spec->cluster.secondMonitorName)); current_spec->cluster.secondMonitorStopped = true; free((yyvsp[(2) - (4)].str)); + break; } - break; - case 36: -#line 353 "test_spec_parse.y" + case 27: +#line 313 "test_spec_parse.y" { strlcpy(current_spec->cluster.secondMonitorName, (yyvsp[(2) - (6)].str), sizeof(current_spec->cluster.secondMonitorName)); @@ -2328,328 +2276,330 @@ yyparse() /* password for second monitor not yet stored */ free((yyvsp[(6) - (6)].str)); + break; } - break; - case 37: -#line 366 "test_spec_parse.y" + case 28: +#line 326 "test_spec_parse.y" { strlcpy(current_spec->cluster.image, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.image)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 38: -#line 372 "test_spec_parse.y" + case 29: +#line 332 "test_spec_parse.y" { strlcpy(current_spec->cluster.image, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.image)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 39: -#line 382 "test_spec_parse.y" + case 30: +#line 342 "test_spec_parse.y" { strlcpy(current_spec->cluster.extensionVersion, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.extensionVersion)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 40: -#line 388 "test_spec_parse.y" + case 31: +#line 348 "test_spec_parse.y" { strlcpy(current_spec->cluster.extensionVersion, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.extensionVersion)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 41: -#line 398 "test_spec_parse.y" + case 32: +#line 358 "test_spec_parse.y" { strlcpy(current_spec->cluster.ssl, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.ssl)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 42: -#line 408 "test_spec_parse.y" + case 33: +#line 368 "test_spec_parse.y" { strlcpy(current_spec->cluster.auth, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.auth)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 43: -#line 414 "test_spec_parse.y" + case 34: +#line 374 "test_spec_parse.y" { strlcpy(current_spec->cluster.auth, (yyvsp[(2) - (2)].str), sizeof(current_spec->cluster.auth)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 44: -#line 424 "test_spec_parse.y" + case 35: +#line 384 "test_spec_parse.y" { TestCluster *cl = ¤t_spec->cluster; if (cl->formationCount >= PGAF_MAX_FORMATIONS) { - fprintf(stderr, "pgaftest: too many formations (max %d)\n", - PGAF_MAX_FORMATIONS); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: too many formations (max %d)\n", + PGAF_MAX_FORMATIONS); exit(1); } current_formation = &cl->formations[cl->formationCount++]; strlcpy(current_formation->name, "default", sizeof(current_formation->name)); current_formation->numSync = -1; + break; } - break; - case 48: -#line 451 "test_spec_parse.y" + case 39: +#line 411 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); + break; } - break; - case 49: -#line 452 "test_spec_parse.y" + case 40: +#line 412 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); + break; } - break; - case 50: -#line 453 "test_spec_parse.y" + case 41: +#line 413 "test_spec_parse.y" { (yyval.str) = strdup("auth"); + break; } - break; - case 51: -#line 454 "test_spec_parse.y" + case 42: +#line 414 "test_spec_parse.y" { (yyval.str) = strdup("monitor"); + break; } - break; - case 52: -#line 455 "test_spec_parse.y" + case 43: +#line 415 "test_spec_parse.y" { (yyval.str) = strdup("node"); + break; } - break; - case 53: -#line 460 "test_spec_parse.y" + case 44: +#line 420 "test_spec_parse.y" { strlcpy(current_formation->name, (yyvsp[(1) - (1)].str), sizeof(current_formation->name)); free((yyvsp[(1) - (1)].str)); + break; } - break; - case 54: -#line 465 "test_spec_parse.y" + case 45: +#line 425 "test_spec_parse.y" { current_formation->numSync = (yyvsp[(2) - (2)].ival); + break; } - break; - case 57: -#line 491 "test_spec_parse.y" + case 48: +#line 451 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); + break; } - break; - case 58: -#line 492 "test_spec_parse.y" + case 49: +#line 452 "test_spec_parse.y" { (yyval.str) = strdup("monitor"); + break; } - break; - case 59: -#line 501 "test_spec_parse.y" + case 50: +#line 461 "test_spec_parse.y" { if (current_formation->nodeCount >= PGAF_MAX_NODES) { - fprintf(stderr, "pgaftest: too many nodes in formation (max %d)\n", - PGAF_MAX_NODES); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: too many nodes in formation (max %d)\n", + PGAF_MAX_NODES); exit(1); } current_node = ¤t_formation->nodes[current_formation->nodeCount++]; current_node->kind = NODE_KIND_STANDALONE; current_node->candidatePriority = 50; current_node->replicationQuorum = true; + break; } - break; - case 60: -#line 518 "test_spec_parse.y" + case 51: +#line 478 "test_spec_parse.y" { strlcpy(current_node->name, (yyvsp[(1) - (2)].str), sizeof(current_node->name)); free((yyvsp[(1) - (2)].str)); + break; } - break; - case 62: -#line 525 "test_spec_parse.y" + case 53: +#line 485 "test_spec_parse.y" { strlcpy(current_node->name, (yyvsp[(2) - (3)].str), sizeof(current_node->name)); free((yyvsp[(2) - (3)].str)); + break; } - break; - case 66: -#line 539 "test_spec_parse.y" + case 57: +#line 499 "test_spec_parse.y" { current_node->kind = NODE_KIND_CITUS_COORDINATOR; current_spec->cluster.withCitus = true; + break; } - break; - case 67: -#line 544 "test_spec_parse.y" + case 58: +#line 504 "test_spec_parse.y" { current_node->kind = NODE_KIND_CITUS_WORKER; current_spec->cluster.withCitus = true; + break; } - break; - case 68: -#line 549 "test_spec_parse.y" + case 59: +#line 509 "test_spec_parse.y" { current_node->replicationQuorum = false; + break; } - break; - case 69: -#line 553 "test_spec_parse.y" + case 60: +#line 513 "test_spec_parse.y" { current_node->noMonitor = true; + break; } - break; - case 70: -#line 557 "test_spec_parse.y" + case 61: +#line 517 "test_spec_parse.y" { current_node->launchDeferred = true; + break; } - break; - case 71: -#line 561 "test_spec_parse.y" + case 62: +#line 521 "test_spec_parse.y" { current_node->launchDeferred = true; + break; } - break; - case 72: -#line 565 "test_spec_parse.y" + case 63: +#line 525 "test_spec_parse.y" { current_node->launchDeferred = false; + break; } - break; - case 73: -#line 569 "test_spec_parse.y" + case 64: +#line 529 "test_spec_parse.y" { current_node->launchDeferred = false; + break; } - break; - case 74: -#line 573 "test_spec_parse.y" + case 65: +#line 533 "test_spec_parse.y" { current_node->listen = true; + break; } - break; - case 75: -#line 577 "test_spec_parse.y" + case 66: +#line 537 "test_spec_parse.y" { current_node->citusSecondary = true; + break; } - break; - case 76: -#line 581 "test_spec_parse.y" + case 67: +#line 541 "test_spec_parse.y" { current_node->candidatePriority = (yyvsp[(2) - (2)].ival); + break; } - break; - case 77: -#line 585 "test_spec_parse.y" + case 68: +#line 545 "test_spec_parse.y" { current_node->group = (yyvsp[(2) - (2)].ival); + break; } - break; - case 78: -#line 589 "test_spec_parse.y" + case 69: +#line 549 "test_spec_parse.y" { current_node->pgPort = (yyvsp[(2) - (2)].ival); + break; } - break; - case 79: -#line 593 "test_spec_parse.y" + case 70: +#line 553 "test_spec_parse.y" { strlcpy(current_node->citusClusterName, (yyvsp[(2) - (2)].str), sizeof(current_node->citusClusterName)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 80: -#line 599 "test_spec_parse.y" + case 71: +#line 559 "test_spec_parse.y" { strlcpy(current_node->debianCluster, (yyvsp[(2) - (2)].str), sizeof(current_node->debianCluster)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 81: -#line 605 "test_spec_parse.y" + case 72: +#line 565 "test_spec_parse.y" { strlcpy(current_node->ssl, (yyvsp[(2) - (2)].str), sizeof(current_node->ssl)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 82: -#line 610 "test_spec_parse.y" + case 73: +#line 570 "test_spec_parse.y" { strlcpy(current_node->auth, (yyvsp[(2) - (2)].str), sizeof(current_node->auth)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 83: -#line 615 "test_spec_parse.y" + case 74: +#line 575 "test_spec_parse.y" { strlcpy(current_node->auth, (yyvsp[(2) - (2)].str), sizeof(current_node->auth)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 84: -#line 620 "test_spec_parse.y" + case 75: +#line 580 "test_spec_parse.y" { if (strcmp((yyvsp[(2) - (2)].str), "false") == 0 || strcmp((yyvsp[(2) - (2)].str), @@ -2662,29 +2612,29 @@ yyparse() current_node->replicationQuorum = true; } free((yyvsp[(2) - (2)].str)); + break; } - break; - case 85: -#line 628 "test_spec_parse.y" + case 76: +#line 588 "test_spec_parse.y" { strlcpy(current_node->replicationPassword, (yyvsp[(2) - (2)].str), sizeof(current_node->replicationPassword)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 86: -#line 634 "test_spec_parse.y" + case 77: +#line 594 "test_spec_parse.y" { strlcpy(current_node->monitorPassword, (yyvsp[(2) - (2)].str), sizeof(current_node->monitorPassword)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 87: -#line 640 "test_spec_parse.y" + case 78: +#line 600 "test_spec_parse.y" { /* volume — adds a named Docker volume */ int vi = current_node->volumeCount; @@ -2698,11 +2648,11 @@ yyparse() } free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 88: -#line 654 "test_spec_parse.y" + case 79: +#line 614 "test_spec_parse.y" { /* volume "/path/with spaces" */ int vi = current_node->volumeCount; @@ -2716,35 +2666,35 @@ yyparse() } free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 89: -#line 675 "test_spec_parse.y" + case 80: +#line 635 "test_spec_parse.y" { current_spec->setup = (yyvsp[(2) - (2)].step); + break; } - break; - case 90: -#line 682 "test_spec_parse.y" + case 81: +#line 642 "test_spec_parse.y" { current_spec->teardown = (yyvsp[(2) - (2)].step); + break; } - break; - case 91: -#line 693 "test_spec_parse.y" + case 82: +#line 653 "test_spec_parse.y" { TestStep *s = (yyvsp[(3) - (3)].step); - strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); + strlcpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name)); free((yyvsp[(2) - (3)].str)); register_step(current_spec, s); + break; } - break; - case 92: -#line 711 "test_spec_parse.y" + case 83: +#line 671 "test_spec_parse.y" { /* post-process: CMD_SQL immediately before CMD_EXPECT_ERROR */ for (TestCmd *c = (yyvsp[(2) - (3)].step)->commands; c; c = c->next) @@ -2756,134 +2706,120 @@ yyparse() } } (yyval.step) = (yyvsp[(2) - (3)].step); + break; } - break; - case 93: -#line 725 "test_spec_parse.y" + case 84: +#line 685 "test_spec_parse.y" { (yyval.step) = make_step(""); + break; } - break; - case 94: -#line 729 "test_spec_parse.y" + case 85: +#line 689 "test_spec_parse.y" { if ((yyvsp[(2) - (2)].cmd)) { append_cmd((yyvsp[(1) - (2)].step), (yyvsp[(2) - (2)].cmd)); } (yyval.step) = (yyvsp[(1) - (2)].step); + break; } - break; - - case 95: -#line 736 "test_spec_parse.y" - { - (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - } - break; - - case 96: -#line 737 "test_spec_parse.y" - { - (yyval.cmd) = (yyvsp[(1) - (1)].cmd); - } - break; - case 97: -#line 738 "test_spec_parse.y" + case 86: +#line 696 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 98: -#line 739 "test_spec_parse.y" + case 87: +#line 697 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 99: -#line 740 "test_spec_parse.y" + case 88: +#line 698 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 100: -#line 741 "test_spec_parse.y" + case 89: +#line 699 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 101: -#line 742 "test_spec_parse.y" + case 90: +#line 700 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 102: -#line 743 "test_spec_parse.y" + case 91: +#line 701 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 103: -#line 744 "test_spec_parse.y" + case 92: +#line 702 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 104: -#line 745 "test_spec_parse.y" + case 93: +#line 703 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 105: -#line 746 "test_spec_parse.y" + case 94: +#line 704 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 106: -#line 747 "test_spec_parse.y" + case 95: +#line 705 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 107: -#line 748 "test_spec_parse.y" + case 96: +#line 706 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 108: -#line 749 "test_spec_parse.y" + case 97: +#line 707 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 109: -#line 750 "test_spec_parse.y" + case 98: +#line 708 "test_spec_parse.y" { (yyval.cmd) = (yyvsp[(1) - (1)].cmd); + break; } - break; - case 110: -#line 765 "test_spec_parse.y" + case 99: +#line 723 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -2892,21 +2828,21 @@ yyparse() sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 111: -#line 772 "test_spec_parse.y" + case 100: +#line 730 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 112: -#line 778 "test_spec_parse.y" + case 101: +#line 736 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC_FAILS); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -2915,21 +2851,21 @@ yyparse() sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 113: -#line 785 "test_spec_parse.y" + case 102: +#line 743 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXEC_FAILS); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 114: -#line 791 "test_spec_parse.y" + case 103: +#line 749 "test_spec_parse.y" { /* "pg_autoctl perform failover --formation auth" * EXEC_ARGS returns T_IDENT for first word, T_SHELL_ARGS for rest */ @@ -2938,28 +2874,28 @@ yyparse() (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 115: -#line 799 "test_spec_parse.y" + case 104: +#line 757 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_PG_AUTOCTL); strlcpy((yyval.cmd)->args, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 116: -#line 805 "test_spec_parse.y" + case 105: +#line 763 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_PG_AUTOCTL); + break; } - break; - case 119: -#line 843 "test_spec_parse.y" + case 108: +#line 801 "test_spec_parse.y" { if (!current_wait_cmd) { @@ -2975,11 +2911,11 @@ yyparse() current_wait_cmd->waitStateCount++; } free((yyvsp[(1) - (4)].str)); + break; } - break; - case 120: -#line 858 "test_spec_parse.y" + case 109: +#line 816 "test_spec_parse.y" { if (!current_wait_cmd) { @@ -2996,11 +2932,11 @@ yyparse() } free((yyvsp[(1) - (4)].str)); free((yyvsp[(4) - (4)].str)); + break; } - break; - case 125: -#line 898 "test_spec_parse.y" + case 114: +#line 856 "test_spec_parse.y" { /* current_pass_cmd set by the enclosing wait_cmd rule */ if (current_pass_cmd && @@ -3012,11 +2948,11 @@ yyparse() (yyvsp[(1) - (1)].str), sizeof(current_pass_cmd->passThroughStates[0])); } + break; } - break; - case 126: -#line 906 "test_spec_parse.y" + case 115: +#line 864 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -3028,11 +2964,11 @@ yyparse() sizeof(current_pass_cmd->passThroughStates[0])); } free((yyvsp[(1) - (1)].str)); + break; } - break; - case 127: -#line 914 "test_spec_parse.y" + case 116: +#line 872 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -3043,11 +2979,11 @@ yyparse() (yyvsp[(3) - (3)].str), sizeof(current_pass_cmd->passThroughStates[0])); } + break; } - break; - case 128: -#line 921 "test_spec_parse.y" + case 117: +#line 879 "test_spec_parse.y" { if (current_pass_cmd && current_pass_cmd->passThroughCount < PGAF_MAX_WAIT_STATES) @@ -3059,11 +2995,11 @@ yyparse() sizeof(current_pass_cmd->passThroughStates[0])); } free((yyvsp[(3) - (3)].str)); + break; } - break; - case 129: -#line 932 "test_spec_parse.y" + case 118: +#line 890 "test_spec_parse.y" { current_pass_cmd = make_cmd(CMD_WAIT_STATE); strlcpy(current_pass_cmd->service, (yyvsp[(3) - (6)].str), @@ -3071,20 +3007,20 @@ yyparse() strlcpy(current_pass_cmd->state, (yyvsp[(6) - (6)].str), sizeof(current_pass_cmd->state)); free((yyvsp[(3) - (6)].str)); + break; } - break; - case 130: -#line 937 "test_spec_parse.y" + case 119: +#line 895 "test_spec_parse.y" { current_pass_cmd->timeoutSeconds = (yyvsp[(9) - (9)].ival); (yyval.cmd) = current_pass_cmd; current_pass_cmd = NULL; + break; } - break; - case 131: -#line 943 "test_spec_parse.y" + case 120: +#line 901 "test_spec_parse.y" { current_pass_cmd = make_cmd(CMD_WAIT_STATE); strlcpy(current_pass_cmd->service, (yyvsp[(3) - (6)].str), @@ -3093,20 +3029,20 @@ yyparse() sizeof(current_pass_cmd->state)); free((yyvsp[(3) - (6)].str)); free((yyvsp[(6) - (6)].str)); + break; } - break; - case 132: -#line 948 "test_spec_parse.y" + case 121: +#line 906 "test_spec_parse.y" { current_pass_cmd->timeoutSeconds = (yyvsp[(9) - (9)].ival); (yyval.cmd) = current_pass_cmd; current_pass_cmd = NULL; + break; } - break; - case 133: -#line 954 "test_spec_parse.y" + case 122: +#line 912 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STATE); (yyval.cmd)->kind = CMD_ASSERT_ASSIGNED; @@ -3116,11 +3052,11 @@ yyparse() sizeof((yyval.cmd)->state)); (yyval.cmd)->timeoutSeconds = (yyvsp[(7) - (7)].ival); free((yyvsp[(3) - (7)].str)); + break; } - break; - case 134: -#line 963 "test_spec_parse.y" + case 123: +#line 921 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STATE); (yyval.cmd)->kind = CMD_ASSERT_ASSIGNED; @@ -3131,59 +3067,59 @@ yyparse() (yyval.cmd)->timeoutSeconds = (yyvsp[(7) - (7)].ival); free((yyvsp[(3) - (7)].str)); free((yyvsp[(6) - (7)].str)); + break; } - break; - case 135: -#line 972 "test_spec_parse.y" + case 124: +#line 930 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_WAIT_STOPPED); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (5)].str), sizeof((yyval.cmd)->service)); (yyval.cmd)->timeoutSeconds = (yyvsp[(5) - (5)].ival); free((yyvsp[(3) - (5)].str)); + break; } - break; - case 136: -#line 979 "test_spec_parse.y" + case 125: +#line 937 "test_spec_parse.y" { (yyval.cmd) = current_wait_cmd; (yyval.cmd)->timeoutSeconds = (yyvsp[(5) - (5)].ival); current_wait_cmd = NULL; + break; } - break; - case 137: -#line 993 "test_spec_parse.y" + case 126: +#line 951 "test_spec_parse.y" { (yyval.cmd) = current_wait_cmd; (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); current_wait_cmd = NULL; + break; } - break; - case 138: -#line 1008 "test_spec_parse.y" + case 127: +#line 966 "test_spec_parse.y" { current_wait_cmd = make_cmd(CMD_WAIT_STATES); strlcpy(current_wait_cmd->waitStates[current_wait_cmd->waitStateCount++], (yyvsp[(1) - (1)].str), sizeof(current_wait_cmd->waitStates[0])); + break; } - break; - case 139: -#line 1014 "test_spec_parse.y" + case 128: +#line 972 "test_spec_parse.y" { current_wait_cmd = make_cmd(CMD_WAIT_STATES); strlcpy(current_wait_cmd->waitStates[current_wait_cmd->waitStateCount++], (yyvsp[(1) - (1)].str), sizeof(current_wait_cmd->waitStates[0])); free((yyvsp[(1) - (1)].str)); + break; } - break; - case 140: -#line 1021 "test_spec_parse.y" + case 129: +#line 979 "test_spec_parse.y" { if (current_wait_cmd->waitStateCount < PGAF_MAX_WAIT_STATES) { @@ -3192,11 +3128,11 @@ yyparse() (yyvsp[(3) - (3)].str), sizeof(current_wait_cmd->waitStates[0])); } + break; } - break; - case 141: -#line 1027 "test_spec_parse.y" + case 130: +#line 985 "test_spec_parse.y" { if (current_wait_cmd->waitStateCount < PGAF_MAX_WAIT_STATES) { @@ -3206,54 +3142,54 @@ yyparse() sizeof(current_wait_cmd->waitStates[0])); } free((yyvsp[(3) - (3)].str)); + break; } - break; - case 144: -#line 1046 "test_spec_parse.y" + case 133: +#line 1004 "test_spec_parse.y" { if (current_wait_cmd->waitGroupCount < PGAF_MAX_WAIT_GROUPS) { current_wait_cmd->waitGroups[current_wait_cmd->waitGroupCount++] = (yyvsp[(2) - (2)].ival); } + break; } - break; - case 145: -#line 1051 "test_spec_parse.y" + case 134: +#line 1009 "test_spec_parse.y" { if (current_wait_cmd->waitGroupCount < PGAF_MAX_WAIT_GROUPS) { current_wait_cmd->waitGroups[current_wait_cmd->waitGroupCount++] = (yyvsp[(4) - (4)].ival); } + break; } - break; - case 146: -#line 1058 "test_spec_parse.y" + case 135: +#line 1016 "test_spec_parse.y" { (yyval.ival) = PGAF_TIMEOUT_DEFAULT; + break; } - break; - case 147: -#line 1059 "test_spec_parse.y" + case 136: +#line 1017 "test_spec_parse.y" { (yyval.ival) = (yyvsp[(2) - (2)].ival); + break; } - break; - case 148: -#line 1060 "test_spec_parse.y" + case 137: +#line 1018 "test_spec_parse.y" { (yyval.ival) = (yyvsp[(3) - (3)].ival); + break; } - break; - case 149: -#line 1072 "test_spec_parse.y" + case 138: +#line 1030 "test_spec_parse.y" { (yyval.cmd) = make_cmd((yyvsp[(6) - (6)].ival) > 0 ? CMD_WAIT_STATE : CMD_ASSERT_STATE); @@ -3263,11 +3199,11 @@ yyparse() sizeof((yyval.cmd)->state)); (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); + break; } - break; - case 150: -#line 1080 "test_spec_parse.y" + case 139: +#line 1038 "test_spec_parse.y" { (yyval.cmd) = make_cmd((yyvsp[(6) - (6)].ival) > 0 ? CMD_WAIT_STATE : CMD_ASSERT_STATE); @@ -3278,11 +3214,11 @@ yyparse() (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); free((yyvsp[(5) - (6)].str)); + break; } - break; - case 151: -#line 1088 "test_spec_parse.y" + case 140: +#line 1046 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_ASSERT_ASSIGNED); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (6)].str), @@ -3291,11 +3227,11 @@ yyparse() sizeof((yyval.cmd)->state)); (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); + break; } - break; - case 152: -#line 1096 "test_spec_parse.y" + case 141: +#line 1054 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_ASSERT_ASSIGNED); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (6)].str), @@ -3305,82 +3241,11 @@ yyparse() (yyval.cmd)->timeoutSeconds = (yyvsp[(6) - (6)].ival); free((yyvsp[(2) - (6)].str)); free((yyvsp[(5) - (6)].str)); + break; } - break; - - case 153: -#line 1104 "test_spec_parse.y" - { - (yyval.cmd) = make_cmd(CMD_ASSERT_STATES); - - /* T_BLOCK contains "node1: draining node2: prepare_promotion" */ - /* Parse name:state pairs inline */ - char *p = (yyvsp[(3) - (3)].str); - while (*p) - { - while (*p == ' ' || *p == '\t' || *p == '\n') - { - p++; - } - if (*p == '\0') - { - break; - } - - /* name */ - char name[64] = { 0 }; - int ni = 0; - while (*p && *p != ':' && *p != ' ' && *p != '\t') - { - if (ni < 63) - { - name[ni++] = *p; - } - p++; - } - while (*p == ' ' || *p == '\t') - { - p++; - } - if (*p == ':') - { - p++; - } - while (*p == ' ' || *p == '\t') - { - p++; - } - - /* state */ - char state[64] = { 0 }; - int si = 0; - while (*p && *p != ' ' && *p != '\t' && *p != '\n') - { - if (si < 63) - { - state[si++] = *p; - } - p++; - } - if (name[0] && state[0]) - { - int idx = (yyval.cmd)->waitStateCount; - if (idx < PGAF_MAX_WAIT_STATES) - { - strlcpy((yyval.cmd)->waitNodes[idx], name, - sizeof((yyval.cmd)->waitNodes[0])); - strlcpy((yyval.cmd)->waitStates[idx], state, - sizeof((yyval.cmd)->waitStates[0])); - (yyval.cmd)->waitStateCount++; - } - } - } - free((yyvsp[(3) - (3)].str)); - } - break; - case 154: -#line 1156 "test_spec_parse.y" + case 142: +#line 1072 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_SQL); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (3)].str), @@ -3389,57 +3254,58 @@ yyparse() sizeof((yyval.cmd)->args)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 155: -#line 1171 "test_spec_parse.y" + case 143: +#line 1087 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT); strlcpy((yyval.cmd)->expected, (yyvsp[(2) - (2)].str), sizeof((yyval.cmd)->expected)); expand_tuple_expect((yyval.cmd)->expected, sizeof((yyval.cmd)->expected)); free((yyvsp[(2) - (2)].str)); + break; } - break; - case 156: -#line 1178 "test_spec_parse.y" + case 144: +#line 1094 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); + break; } - break; - case 157: -#line 1182 "test_spec_parse.y" + case 145: +#line 1098 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); strlcpy((yyval.cmd)->state, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->state)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 158: -#line 1188 "test_spec_parse.y" + case 146: +#line 1104 "test_spec_parse.y" { /* SQLSTATE codes like 25006 are all digits, lexed as T_INTEGER */ (yyval.cmd) = make_cmd(CMD_EXPECT_ERROR); - snprintf((yyval.cmd)->state, sizeof((yyval.cmd)->state), "%d", - (yyvsp[(3) - (3)].ival)); + snprintf(/* IGNORE-BANNED */ (yyval.cmd)->state, + sizeof((yyval.cmd)->state), "%d", + (yyvsp[(3) - (3)].ival)); + break; } - break; - case 159: -#line 1201 "test_spec_parse.y" + case 147: +#line 1117 "test_spec_parse.y" { (yyval.cmd) = current_promote_cmd; current_promote_cmd = NULL; + break; } - break; - case 160: -#line 1209 "test_spec_parse.y" + case 148: +#line 1125 "test_spec_parse.y" { current_promote_cmd = make_cmd(CMD_PROMOTE); current_promote_cmd->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; @@ -3448,11 +3314,11 @@ yyparse() (yyvsp[(1) - (1)].str), sizeof(current_promote_cmd->promoteNodes[0])); free((yyvsp[(1) - (1)].str)); + break; } - break; - case 161: -#line 1217 "test_spec_parse.y" + case 149: +#line 1133 "test_spec_parse.y" { if (current_promote_cmd->promoteCount < PGAF_MAX_PROMOTE_NODES) { @@ -3463,76 +3329,76 @@ yyparse() sizeof(current_promote_cmd->promoteNodes[0])); } free((yyvsp[(3) - (3)].str)); + break; } - break; - case 162: -#line 1232 "test_spec_parse.y" + case 150: +#line 1148 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_NETWORK_OFF); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 163: -#line 1238 "test_spec_parse.y" + case 151: +#line 1154 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_NETWORK_ON); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 164: -#line 1251 "test_spec_parse.y" + case 152: +#line 1167 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_SLEEP); (yyval.cmd)->timeoutSeconds = (yyvsp[(2) - (2)].ival); + break; } - break; - case 165: -#line 1265 "test_spec_parse.y" + case 153: +#line 1181 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_DOWN); + break; } - break; - case 166: -#line 1269 "test_spec_parse.y" + case 154: +#line 1185 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_START); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 167: -#line 1275 "test_spec_parse.y" + case 155: +#line 1191 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_STOP); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 168: -#line 1281 "test_spec_parse.y" + case 156: +#line 1197 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_KILL); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 169: -#line 1307 "test_spec_parse.y" + case 157: +#line 1223 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_COMPOSE_INJECT); strlcpy((yyval.cmd)->expected, (yyvsp[(3) - (4)].str), @@ -3566,45 +3432,45 @@ yyparse() } free((yyvsp[(3) - (4)].str)); free((yyvsp[(4) - (4)].str)); + break; } - break; - case 170: -#line 1341 "test_spec_parse.y" + case 158: +#line 1257 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_STOP_POSTGRES); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 171: -#line 1347 "test_spec_parse.y" + case 159: +#line 1263 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_START_POSTGRES); strlcpy((yyval.cmd)->service, (yyvsp[(3) - (3)].str), sizeof((yyval.cmd)->service)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 172: -#line 1363 "test_spec_parse.y" + case 160: +#line 1279 "test_spec_parse.y" { pgaf_next_brace_is_while = 1; + break; } - break; - case 173: -#line 1364 "test_spec_parse.y" + case 161: +#line 1280 "test_spec_parse.y" { (yyval.step) = (yyvsp[(4) - (5)].step); + break; } - break; - case 174: -#line 1369 "test_spec_parse.y" + case 162: +#line 1285 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_STAYS_WHILE); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3615,20 +3481,20 @@ yyparse() (5)].step)-> commands : NULL; free((yyvsp[(2) - (5)].str)); + break; } - break; - case 175: -#line 1388 "test_spec_parse.y" + case 163: +#line 1304 "test_spec_parse.y" { /* only "set monitor " is supported; $2 must be "monitor" */ if (strcmp((yyvsp[(2) - (3)].str), "monitor") != 0) { - fprintf(stderr, - "pgaftest: unknown 'set' target '%s' (expected 'monitor')\n", - (yyvsp[(2) - - ( - 3)].str)); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: unknown 'set' target '%s' (expected 'monitor')\n", + (yyvsp[(2) - + ( + 3)].str)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); YYERROR; @@ -3638,11 +3504,11 @@ yyparse() sizeof((yyval.cmd)->service)); free((yyvsp[(2) - (3)].str)); free((yyvsp[(3) - (3)].str)); + break; } - break; - case 176: -#line 1413 "test_spec_parse.y" + case 164: +#line 1329 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (4)].str), @@ -3653,11 +3519,11 @@ yyparse() (yyval.cmd)->allowError = false; /* false = fixed string, true = PCRE */ free((yyvsp[(2) - (4)].str)); free((yyvsp[(4) - (4)].str)); + break; } - break; - case 177: -#line 1422 "test_spec_parse.y" + case 165: +#line 1338 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3668,11 +3534,11 @@ yyparse() (yyval.cmd)->allowError = false; free((yyvsp[(2) - (5)].str)); free((yyvsp[(5) - (5)].str)); + break; } - break; - case 178: -#line 1431 "test_spec_parse.y" + case 166: +#line 1347 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (4)].str), @@ -3683,11 +3549,11 @@ yyparse() (yyval.cmd)->allowError = true; /* true = PCRE (-P) */ free((yyvsp[(2) - (4)].str)); free((yyvsp[(4) - (4)].str)); + break; } - break; - case 179: -#line 1440 "test_spec_parse.y" + case 167: +#line 1356 "test_spec_parse.y" { (yyval.cmd) = make_cmd(CMD_LOGS_CHECK); strlcpy((yyval.cmd)->service, (yyvsp[(2) - (5)].str), @@ -3698,67 +3564,11 @@ yyparse() (yyval.cmd)->allowError = true; free((yyvsp[(2) - (5)].str)); free((yyvsp[(5) - (5)].str)); + break; } - break; - case 180: -#line 1461 "test_spec_parse.y" - { - if (!current_spec->cluster.monitorApiOnly) - { - yyerror("node_active is only allowed inside a scenario { } block; " - "use a cluster { } block for full docker compose tests"); - } - (yyval.cmd) = make_cmd(CMD_NODE_ACTIVE); - - /* $2 = "node2 reported: secondary lsn: 0/5A0 ..." */ - strlcpy((yyval.cmd)->args, (yyvsp[(2) - (4)].str), - sizeof((yyval.cmd)->args)); - - /* $4 = "assigned: secondary" */ - strlcpy((yyval.cmd)->nodeActiveExpected, (yyvsp[(4) - (4)].str), - sizeof((yyval.cmd)->nodeActiveExpected)); - free((yyvsp[(2) - (4)].str)); - free((yyvsp[(4) - (4)].str)); - } - break; - - case 181: -#line 1483 "test_spec_parse.y" - { - if (!current_spec->cluster.monitorApiOnly) - { - yyerror( - "mark healthy/unhealthy is only allowed inside a scenario { } " - "block; use a cluster { } block for full docker compose tests"); - } - (yyval.cmd) = make_cmd(CMD_MARK_HEALTH); - strlcpy((yyval.cmd)->service, (yyvsp[(4) - (4)].str), - sizeof((yyval.cmd)->service)); - (yyval.cmd)->markHealthy = true; - free((yyvsp[(4) - (4)].str)); - } - break; - - case 182: -#line 1495 "test_spec_parse.y" - { - if (!current_spec->cluster.monitorApiOnly) - { - yyerror( - "mark healthy/unhealthy is only allowed inside a scenario { } " - "block; use a cluster { } block for full docker compose tests"); - } - (yyval.cmd) = make_cmd(CMD_MARK_HEALTH); - strlcpy((yyval.cmd)->service, (yyvsp[(4) - (4)].str), - sizeof((yyval.cmd)->service)); - (yyval.cmd)->markHealthy = false; - free((yyvsp[(4) - (4)].str)); - } - break; - - case 185: -#line 1519 "test_spec_parse.y" + case 170: +#line 1377 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -3769,177 +3579,178 @@ yyparse() } else { - fprintf(stderr, "pgaftest: too many steps in sequence (max %d)\n", - PGAF_MAX_SEQ); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: too many steps in sequence (max %d)\n", + PGAF_MAX_SEQ); exit(1); } + break; } - break; - case 186: -#line 1540 "test_spec_parse.y" + case 171: +#line 1398 "test_spec_parse.y" { (yyval.str) = "init"; + break; } - break; - case 187: -#line 1541 "test_spec_parse.y" + case 172: +#line 1399 "test_spec_parse.y" { (yyval.str) = "single"; + break; } - break; - case 188: -#line 1542 "test_spec_parse.y" + case 173: +#line 1400 "test_spec_parse.y" { (yyval.str) = "primary"; + break; } - break; - case 189: -#line 1543 "test_spec_parse.y" + case 174: +#line 1401 "test_spec_parse.y" { (yyval.str) = "wait_primary"; + break; } - break; - case 190: -#line 1544 "test_spec_parse.y" + case 175: +#line 1402 "test_spec_parse.y" { (yyval.str) = "wait_standby"; + break; } - break; - case 191: -#line 1545 "test_spec_parse.y" + case 176: +#line 1403 "test_spec_parse.y" { (yyval.str) = "demoted"; + break; } - break; - case 192: -#line 1546 "test_spec_parse.y" + case 177: +#line 1404 "test_spec_parse.y" { (yyval.str) = "demote_timeout"; + break; } - break; - case 193: -#line 1547 "test_spec_parse.y" + case 178: +#line 1405 "test_spec_parse.y" { (yyval.str) = "draining"; + break; } - break; - case 194: -#line 1548 "test_spec_parse.y" + case 179: +#line 1406 "test_spec_parse.y" { (yyval.str) = "secondary"; + break; } - break; - case 195: -#line 1549 "test_spec_parse.y" + case 180: +#line 1407 "test_spec_parse.y" { (yyval.str) = "catchingup"; + break; } - break; - case 196: -#line 1550 "test_spec_parse.y" + case 181: +#line 1408 "test_spec_parse.y" { (yyval.str) = "prepare_promotion"; + break; } - break; - case 197: -#line 1551 "test_spec_parse.y" + case 182: +#line 1409 "test_spec_parse.y" { (yyval.str) = "stop_replication"; + break; } - break; - case 198: -#line 1552 "test_spec_parse.y" + case 183: +#line 1410 "test_spec_parse.y" { (yyval.str) = "maintenance"; + break; } - break; - case 199: -#line 1553 "test_spec_parse.y" + case 184: +#line 1411 "test_spec_parse.y" { (yyval.str) = "join_primary"; + break; } - break; - case 200: -#line 1554 "test_spec_parse.y" + case 185: +#line 1412 "test_spec_parse.y" { (yyval.str) = "apply_settings"; + break; } - break; - case 201: -#line 1555 "test_spec_parse.y" + case 186: +#line 1413 "test_spec_parse.y" { (yyval.str) = "prepare_maintenance"; + break; } - break; - case 202: -#line 1556 "test_spec_parse.y" + case 187: +#line 1414 "test_spec_parse.y" { (yyval.str) = "wait_maintenance"; + break; } - break; - case 203: -#line 1557 "test_spec_parse.y" + case 188: +#line 1415 "test_spec_parse.y" { (yyval.str) = "report_lsn"; + break; } - break; - case 204: -#line 1558 "test_spec_parse.y" + case 189: +#line 1416 "test_spec_parse.y" { (yyval.str) = "fast_forward"; + break; } - break; - case 205: -#line 1559 "test_spec_parse.y" + case 190: +#line 1417 "test_spec_parse.y" { (yyval.str) = "join_secondary"; + break; } - break; - case 206: -#line 1560 "test_spec_parse.y" + case 191: +#line 1418 "test_spec_parse.y" { (yyval.str) = "dropped"; + break; } - break; - case 207: -#line 1568 "test_spec_parse.y" + case 192: +#line 1426 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); + break; } - break; - case 208: -#line 1569 "test_spec_parse.y" + case 193: +#line 1427 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); + break; } - break; /* Line 1267 of yacc.c. */ -#line 3516 "test_spec_parse.c" +#line 3360 "test_spec_parse.c" default: { } break; @@ -4187,7 +3998,7 @@ yyparse() } -#line 1572 "test_spec_parse.y" +#line 1430 "test_spec_parse.y" /* ----------------------------------------------------------------------- @@ -4196,22 +4007,23 @@ yyparse() TestSpec * parse_test_spec(const char *filename) { - FILE *f = fopen(filename, "r"); + FILE *f = fopen(filename, "r"); /* IGNORE-BANNED */ if (!f) { - fprintf(stderr, "pgaftest: cannot open spec file \"%s\": %s\n", - filename, strerror(errno)); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: cannot open spec file \"%s\": %s\n", + filename, strerror(errno) /* IGNORE-BANNED */); return NULL; } TestSpec *spec = (TestSpec *) calloc(1, sizeof(TestSpec)); if (!spec) { - fprintf(stderr, "out of memory\n"); + fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ exit(1); } - strncpy(spec->filename, filename, sizeof(spec->filename) - 1); + strlcpy(spec->filename, filename, sizeof(spec->filename)); current_spec = spec; pgaf_line_number = 1; @@ -4229,7 +4041,7 @@ make_cmd(TestCmdKind kind) TestCmd *c = (TestCmd *) calloc(1, sizeof(TestCmd)); if (!c) { - fprintf(stderr, "out of memory\n"); + fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ exit(1); } c->kind = kind; @@ -4244,12 +4056,12 @@ make_step(const char *name) TestStep *s = (TestStep *) calloc(1, sizeof(TestStep)); if (!s) { - fprintf(stderr, "out of memory\n"); + fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ exit(1); } if (name) { - strncpy(s->name, name, sizeof(s->name) - 1); + strlcpy(s->name, name, sizeof(s->name)); } return s; } diff --git a/src/bin/pgaftest/test_spec_parse.h b/src/bin/pgaftest/test_spec_parse.h index aabb5eec8..6f62d6019 100644 --- a/src/bin/pgaftest/test_spec_parse.h +++ b/src/bin/pgaftest/test_spec_parse.h @@ -42,231 +42,219 @@ enum yytokentype { T_CLUSTER = 258, - T_SCENARIO = 259, - T_MONITOR = 260, - T_NODE = 261, - T_CITUS_COORDINATOR = 262, - T_CITUS_WORKER = 263, - T_SETUP = 264, - T_TEARDOWN = 265, - T_STEP = 266, - T_SEQUENCE = 267, - T_EQUALS = 268, - T_IMAGE = 269, - T_IMAGE_TARGET = 270, - T_SSL = 271, - T_AUTH = 272, - T_AUTH_METHOD = 273, - T_FORMATION = 274, - T_NUM_SYNC = 275, - T_COORDINATOR = 276, - T_WORKER = 277, - T_ASYNC = 278, - T_NO_MONITOR = 279, - T_LAUNCH = 280, - T_DEFERRED = 281, - T_IMMEDIATE = 282, - T_INITIALLY = 283, - T_VOLUME = 284, - T_LISTEN = 285, - T_CITUS_SECONDARY = 286, - T_CANDIDATE_PRIORITY = 287, - T_PORT = 288, - T_PASSWORD = 289, - T_MONITOR_PASSWORD = 290, - T_CITUS_CLUSTER_NAME = 291, - T_DEBIAN_CLUSTER = 292, - T_REPLICATION_QUORUM = 293, - T_REPLICATION_PASSWORD = 294, - T_EXTENSION_VERSION = 295, - T_BIND_SOURCE = 296, - T_FS_INIT = 297, - T_FS_SINGLE = 298, - T_FS_PRIMARY = 299, - T_FS_WAIT_PRIMARY = 300, - T_FS_WAIT_STANDBY = 301, - T_FS_DEMOTED = 302, - T_FS_DEMOTE_TIMEOUT = 303, - T_FS_DRAINING = 304, - T_FS_SECONDARY = 305, - T_FS_CATCHINGUP = 306, - T_FS_PREP_PROMOTION = 307, - T_FS_STOP_REPLICATION = 308, - T_FS_MAINTENANCE = 309, - T_FS_JOIN_PRIMARY = 310, - T_FS_APPLY_SETTINGS = 311, - T_FS_PREPARE_MAINTENANCE = 312, - T_FS_WAIT_MAINTENANCE = 313, - T_FS_REPORT_LSN = 314, - T_FS_FAST_FORWARD = 315, - T_FS_JOIN_SECONDARY = 316, - T_FS_DROPPED = 317, - T_EXEC = 318, - T_EXEC_FAILS = 319, - T_PG_AUTOCTL = 320, - T_WAIT = 321, - T_UNTIL = 322, - T_TIMEOUT = 323, - T_AND = 324, - T_IS = 325, - T_WITH = 326, - T_ASSERT = 327, - T_SQL = 328, - T_EXPECT = 329, - T_ERROR = 330, - T_PROMOTE = 331, - T_NETWORK = 332, - T_DISCONNECT = 333, - T_CONNECT = 334, - T_SLEEP = 335, - T_COMPOSE = 336, - T_DOWN = 337, - T_START = 338, - T_STOP = 339, - T_STOPPED = 340, - T_KILL = 341, - T_INJECT = 342, - T_STATE = 343, - T_ASSIGNED_STATE = 344, - T_IN = 345, - T_GROUP = 346, - T_LBRACE = 347, - T_RBRACE = 348, - T_COMMA = 349, - T_POSTGRES = 350, - T_STAYS = 351, - T_WHILE = 352, - T_THROUGH = 353, - T_SET = 354, - T_LOGS = 355, - T_NOT = 356, - T_CONTAINS = 357, - T_MATCHES = 358, - T_NODE_ACTIVE = 359, - T_MARK = 360, - T_HEALTHY = 361, - T_UNHEALTHY = 362, - T_STATES = 363, - T_INTEGER = 364, - T_IDENT = 365, - T_STRING = 366, - T_BLOCK = 367, - T_SHELL_ARGS = 368 + T_MONITOR = 259, + T_NODE = 260, + T_CITUS_COORDINATOR = 261, + T_CITUS_WORKER = 262, + T_SETUP = 263, + T_TEARDOWN = 264, + T_STEP = 265, + T_SEQUENCE = 266, + T_EQUALS = 267, + T_IMAGE = 268, + T_IMAGE_TARGET = 269, + T_SSL = 270, + T_AUTH = 271, + T_AUTH_METHOD = 272, + T_FORMATION = 273, + T_NUM_SYNC = 274, + T_COORDINATOR = 275, + T_WORKER = 276, + T_ASYNC = 277, + T_NO_MONITOR = 278, + T_LAUNCH = 279, + T_DEFERRED = 280, + T_IMMEDIATE = 281, + T_INITIALLY = 282, + T_VOLUME = 283, + T_LISTEN = 284, + T_CITUS_SECONDARY = 285, + T_CANDIDATE_PRIORITY = 286, + T_PORT = 287, + T_PASSWORD = 288, + T_MONITOR_PASSWORD = 289, + T_CITUS_CLUSTER_NAME = 290, + T_DEBIAN_CLUSTER = 291, + T_REPLICATION_QUORUM = 292, + T_REPLICATION_PASSWORD = 293, + T_EXTENSION_VERSION = 294, + T_BIND_SOURCE = 295, + T_FS_INIT = 296, + T_FS_SINGLE = 297, + T_FS_PRIMARY = 298, + T_FS_WAIT_PRIMARY = 299, + T_FS_WAIT_STANDBY = 300, + T_FS_DEMOTED = 301, + T_FS_DEMOTE_TIMEOUT = 302, + T_FS_DRAINING = 303, + T_FS_SECONDARY = 304, + T_FS_CATCHINGUP = 305, + T_FS_PREP_PROMOTION = 306, + T_FS_STOP_REPLICATION = 307, + T_FS_MAINTENANCE = 308, + T_FS_JOIN_PRIMARY = 309, + T_FS_APPLY_SETTINGS = 310, + T_FS_PREPARE_MAINTENANCE = 311, + T_FS_WAIT_MAINTENANCE = 312, + T_FS_REPORT_LSN = 313, + T_FS_FAST_FORWARD = 314, + T_FS_JOIN_SECONDARY = 315, + T_FS_DROPPED = 316, + T_EXEC = 317, + T_EXEC_FAILS = 318, + T_PG_AUTOCTL = 319, + T_WAIT = 320, + T_UNTIL = 321, + T_TIMEOUT = 322, + T_AND = 323, + T_IS = 324, + T_WITH = 325, + T_ASSERT = 326, + T_SQL = 327, + T_EXPECT = 328, + T_ERROR = 329, + T_PROMOTE = 330, + T_NETWORK = 331, + T_DISCONNECT = 332, + T_CONNECT = 333, + T_SLEEP = 334, + T_COMPOSE = 335, + T_DOWN = 336, + T_START = 337, + T_STOP = 338, + T_STOPPED = 339, + T_KILL = 340, + T_INJECT = 341, + T_STATE = 342, + T_ASSIGNED_STATE = 343, + T_IN = 344, + T_GROUP = 345, + T_LBRACE = 346, + T_RBRACE = 347, + T_COMMA = 348, + T_POSTGRES = 349, + T_STAYS = 350, + T_WHILE = 351, + T_THROUGH = 352, + T_SET = 353, + T_LOGS = 354, + T_NOT = 355, + T_CONTAINS = 356, + T_MATCHES = 357, + T_INTEGER = 358, + T_IDENT = 359, + T_STRING = 360, + T_BLOCK = 361, + T_SHELL_ARGS = 362 }; #endif /* Tokens. */ #define T_CLUSTER 258 -#define T_SCENARIO 259 -#define T_MONITOR 260 -#define T_NODE 261 -#define T_CITUS_COORDINATOR 262 -#define T_CITUS_WORKER 263 -#define T_SETUP 264 -#define T_TEARDOWN 265 -#define T_STEP 266 -#define T_SEQUENCE 267 -#define T_EQUALS 268 -#define T_IMAGE 269 -#define T_IMAGE_TARGET 270 -#define T_SSL 271 -#define T_AUTH 272 -#define T_AUTH_METHOD 273 -#define T_FORMATION 274 -#define T_NUM_SYNC 275 -#define T_COORDINATOR 276 -#define T_WORKER 277 -#define T_ASYNC 278 -#define T_NO_MONITOR 279 -#define T_LAUNCH 280 -#define T_DEFERRED 281 -#define T_IMMEDIATE 282 -#define T_INITIALLY 283 -#define T_VOLUME 284 -#define T_LISTEN 285 -#define T_CITUS_SECONDARY 286 -#define T_CANDIDATE_PRIORITY 287 -#define T_PORT 288 -#define T_PASSWORD 289 -#define T_MONITOR_PASSWORD 290 -#define T_CITUS_CLUSTER_NAME 291 -#define T_DEBIAN_CLUSTER 292 -#define T_REPLICATION_QUORUM 293 -#define T_REPLICATION_PASSWORD 294 -#define T_EXTENSION_VERSION 295 -#define T_BIND_SOURCE 296 -#define T_FS_INIT 297 -#define T_FS_SINGLE 298 -#define T_FS_PRIMARY 299 -#define T_FS_WAIT_PRIMARY 300 -#define T_FS_WAIT_STANDBY 301 -#define T_FS_DEMOTED 302 -#define T_FS_DEMOTE_TIMEOUT 303 -#define T_FS_DRAINING 304 -#define T_FS_SECONDARY 305 -#define T_FS_CATCHINGUP 306 -#define T_FS_PREP_PROMOTION 307 -#define T_FS_STOP_REPLICATION 308 -#define T_FS_MAINTENANCE 309 -#define T_FS_JOIN_PRIMARY 310 -#define T_FS_APPLY_SETTINGS 311 -#define T_FS_PREPARE_MAINTENANCE 312 -#define T_FS_WAIT_MAINTENANCE 313 -#define T_FS_REPORT_LSN 314 -#define T_FS_FAST_FORWARD 315 -#define T_FS_JOIN_SECONDARY 316 -#define T_FS_DROPPED 317 -#define T_EXEC 318 -#define T_EXEC_FAILS 319 -#define T_PG_AUTOCTL 320 -#define T_WAIT 321 -#define T_UNTIL 322 -#define T_TIMEOUT 323 -#define T_AND 324 -#define T_IS 325 -#define T_WITH 326 -#define T_ASSERT 327 -#define T_SQL 328 -#define T_EXPECT 329 -#define T_ERROR 330 -#define T_PROMOTE 331 -#define T_NETWORK 332 -#define T_DISCONNECT 333 -#define T_CONNECT 334 -#define T_SLEEP 335 -#define T_COMPOSE 336 -#define T_DOWN 337 -#define T_START 338 -#define T_STOP 339 -#define T_STOPPED 340 -#define T_KILL 341 -#define T_INJECT 342 -#define T_STATE 343 -#define T_ASSIGNED_STATE 344 -#define T_IN 345 -#define T_GROUP 346 -#define T_LBRACE 347 -#define T_RBRACE 348 -#define T_COMMA 349 -#define T_POSTGRES 350 -#define T_STAYS 351 -#define T_WHILE 352 -#define T_THROUGH 353 -#define T_SET 354 -#define T_LOGS 355 -#define T_NOT 356 -#define T_CONTAINS 357 -#define T_MATCHES 358 -#define T_NODE_ACTIVE 359 -#define T_MARK 360 -#define T_HEALTHY 361 -#define T_UNHEALTHY 362 -#define T_STATES 363 -#define T_INTEGER 364 -#define T_IDENT 365 -#define T_STRING 366 -#define T_BLOCK 367 -#define T_SHELL_ARGS 368 +#define T_MONITOR 259 +#define T_NODE 260 +#define T_CITUS_COORDINATOR 261 +#define T_CITUS_WORKER 262 +#define T_SETUP 263 +#define T_TEARDOWN 264 +#define T_STEP 265 +#define T_SEQUENCE 266 +#define T_EQUALS 267 +#define T_IMAGE 268 +#define T_IMAGE_TARGET 269 +#define T_SSL 270 +#define T_AUTH 271 +#define T_AUTH_METHOD 272 +#define T_FORMATION 273 +#define T_NUM_SYNC 274 +#define T_COORDINATOR 275 +#define T_WORKER 276 +#define T_ASYNC 277 +#define T_NO_MONITOR 278 +#define T_LAUNCH 279 +#define T_DEFERRED 280 +#define T_IMMEDIATE 281 +#define T_INITIALLY 282 +#define T_VOLUME 283 +#define T_LISTEN 284 +#define T_CITUS_SECONDARY 285 +#define T_CANDIDATE_PRIORITY 286 +#define T_PORT 287 +#define T_PASSWORD 288 +#define T_MONITOR_PASSWORD 289 +#define T_CITUS_CLUSTER_NAME 290 +#define T_DEBIAN_CLUSTER 291 +#define T_REPLICATION_QUORUM 292 +#define T_REPLICATION_PASSWORD 293 +#define T_EXTENSION_VERSION 294 +#define T_BIND_SOURCE 295 +#define T_FS_INIT 296 +#define T_FS_SINGLE 297 +#define T_FS_PRIMARY 298 +#define T_FS_WAIT_PRIMARY 299 +#define T_FS_WAIT_STANDBY 300 +#define T_FS_DEMOTED 301 +#define T_FS_DEMOTE_TIMEOUT 302 +#define T_FS_DRAINING 303 +#define T_FS_SECONDARY 304 +#define T_FS_CATCHINGUP 305 +#define T_FS_PREP_PROMOTION 306 +#define T_FS_STOP_REPLICATION 307 +#define T_FS_MAINTENANCE 308 +#define T_FS_JOIN_PRIMARY 309 +#define T_FS_APPLY_SETTINGS 310 +#define T_FS_PREPARE_MAINTENANCE 311 +#define T_FS_WAIT_MAINTENANCE 312 +#define T_FS_REPORT_LSN 313 +#define T_FS_FAST_FORWARD 314 +#define T_FS_JOIN_SECONDARY 315 +#define T_FS_DROPPED 316 +#define T_EXEC 317 +#define T_EXEC_FAILS 318 +#define T_PG_AUTOCTL 319 +#define T_WAIT 320 +#define T_UNTIL 321 +#define T_TIMEOUT 322 +#define T_AND 323 +#define T_IS 324 +#define T_WITH 325 +#define T_ASSERT 326 +#define T_SQL 327 +#define T_EXPECT 328 +#define T_ERROR 329 +#define T_PROMOTE 330 +#define T_NETWORK 331 +#define T_DISCONNECT 332 +#define T_CONNECT 333 +#define T_SLEEP 334 +#define T_COMPOSE 335 +#define T_DOWN 336 +#define T_START 337 +#define T_STOP 338 +#define T_STOPPED 339 +#define T_KILL 340 +#define T_INJECT 341 +#define T_STATE 342 +#define T_ASSIGNED_STATE 343 +#define T_IN 344 +#define T_GROUP 345 +#define T_LBRACE 346 +#define T_RBRACE 347 +#define T_COMMA 348 +#define T_POSTGRES 349 +#define T_STAYS 350 +#define T_WHILE 351 +#define T_THROUGH 352 +#define T_SET 353 +#define T_LOGS 354 +#define T_NOT 355 +#define T_CONTAINS 356 +#define T_MATCHES 357 +#define T_INTEGER 358 +#define T_IDENT 359 +#define T_STRING 360 +#define T_BLOCK 361 +#define T_SHELL_ARGS 362 #if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED @@ -280,7 +268,7 @@ typedef union YYSTYPE } /* Line 1529 of yacc.c. */ -#line 282 "test_spec_parse.h" +#line 270 "test_spec_parse.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index adc6f47be..9af5fc113 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -150,7 +150,7 @@ static TestNode *current_node = NULL; } /* ---- Outer-structure tokens (used in INITIAL lex state) ---- */ -%token T_CLUSTER T_SCENARIO T_MONITOR T_NODE T_CITUS_COORDINATOR T_CITUS_WORKER +%token T_CLUSTER T_MONITOR T_NODE T_CITUS_COORDINATOR T_CITUS_WORKER %token T_SETUP T_TEARDOWN T_STEP T_SEQUENCE %token T_EQUALS @@ -187,7 +187,6 @@ static TestNode *current_node = NULL; %token T_LBRACE T_RBRACE T_COMMA %token T_POSTGRES T_STAYS T_WHILE T_THROUGH T_SET %token T_LOGS T_NOT T_CONTAINS T_MATCHES -%token T_NODE_ACTIVE T_MARK T_HEALTHY T_UNHEALTHY T_STATES /* ---- Tokens with values ---- */ %token T_INTEGER @@ -203,7 +202,6 @@ static TestNode *current_node = NULL; %type exec_cmd wait_cmd assert_cmd sql_cmd expect_cmd %type promote_cmd network_cmd sleep_cmd compose_cmd %type postgres_ctl_cmd stays_while_cmd set_monitor_cmd logs_cmd -%type node_active_cmd mark_health_cmd %type opt_timeout %type while_body @@ -216,7 +214,6 @@ spec: spec_item: cluster_block - | scenario_block | setup_block | teardown_block | named_step @@ -242,43 +239,6 @@ cluster_block: cluster_item_list T_RBRACE ; -/* ----------------------------------------------------------------------- - * scenario { } - * - * A monitor-API-only test scenario. Only the monitor service is - * provisioned; node names in the formation block are virtual (no - * containers are created for them). The node_active and mark_health - * commands are restricted to specs declared with this keyword. - * - * The lexer reuses the CLUSTER_BODY state for the scenario body so all - * the existing formation / node-name tokens are available. - * ----------------------------------------------------------------------- */ - -scenario_block: - T_SCENARIO T_LBRACE - { - current_spec->cluster.monitorApiOnly = true; - current_spec->cluster.withMonitor = true; - strlcpy(current_spec->cluster.ssl, "self-signed", - sizeof(current_spec->cluster.ssl)); - strlcpy(current_spec->cluster.auth, "trust", - sizeof(current_spec->cluster.auth)); - } - scenario_item_list T_RBRACE - ; - -scenario_item_list: - /* empty */ - | scenario_item_list scenario_item - ; - -scenario_item: - formation_block - | image_line - | ssl_line - | auth_line - ; - cluster_item_list: /* empty */ | cluster_item_list cluster_item @@ -746,8 +706,6 @@ step_cmd: | stays_while_cmd { $$ = $1; } | set_monitor_cmd { $$ = $1; } | logs_cmd { $$ = $1; } - | node_active_cmd { $$ = $1; } - | mark_health_cmd { $$ = $1; } ; /* ----------------------------------------------------------------------- @@ -1100,48 +1058,6 @@ assert_cmd: $$->timeoutSeconds = $6; free($2); free($5); } - | T_ASSERT T_STATES T_BLOCK - { - $$ = make_cmd(CMD_ASSERT_STATES); - /* T_BLOCK contains "node1: draining node2: prepare_promotion" */ - /* Parse name:state pairs inline */ - char *p = $3; - while (*p) - { - while (*p == ' ' || *p == '\t' || *p == '\n') p++; - if (*p == '\0') break; - /* name */ - char name[64] = { 0 }; - int ni = 0; - while (*p && *p != ':' && *p != ' ' && *p != '\t') - { - if (ni < 63) name[ni++] = *p; - p++; - } - while (*p == ' ' || *p == '\t') p++; - if (*p == ':') p++; - while (*p == ' ' || *p == '\t') p++; - /* state */ - char state[64] = { 0 }; - int si = 0; - while (*p && *p != ' ' && *p != '\t' && *p != '\n') - { - if (si < 63) state[si++] = *p; - p++; - } - if (name[0] && state[0]) - { - int idx = $$->waitStateCount; - if (idx < PGAF_MAX_WAIT_STATES) - { - strlcpy($$->waitNodes[idx], name, sizeof($$->waitNodes[0])); - strlcpy($$->waitStates[idx], state, sizeof($$->waitStates[0])); - $$->waitStateCount++; - } - } - } - free($3); - } ; /* ----------------------------------------------------------------------- @@ -1447,64 +1363,6 @@ logs_cmd: } ; -/* ----------------------------------------------------------------------- - * node_active { reported: lsn: [tli: N] [pgrunning: bool] } - * expect { assigned: } - * - * The key-value pairs inside the { } braces are read as a raw T_BLOCK string - * and parsed in C by the runner. This keeps the grammar simple and avoids - * introducing a lex state for the block content. - * ----------------------------------------------------------------------- */ - -node_active_cmd: - T_NODE_ACTIVE T_BLOCK T_EXPECT T_BLOCK - { - if (!current_spec->cluster.monitorApiOnly) - { - yyerror("node_active is only allowed inside a scenario { } block; " - "use a cluster { } block for full docker compose tests"); - } - $$ = make_cmd(CMD_NODE_ACTIVE); - /* $2 = "node2 reported: secondary lsn: 0/5A0 ..." */ - strlcpy($$->args, $2, sizeof($$->args)); - /* $4 = "assigned: secondary" */ - strlcpy($$->nodeActiveExpected, $4, sizeof($$->nodeActiveExpected)); - free($2); free($4); - } - ; - -/* ----------------------------------------------------------------------- - * mark healthy: - * mark unhealthy: - * ----------------------------------------------------------------------- */ - -mark_health_cmd: - T_MARK T_HEALTHY ':' T_IDENT - { - if (!current_spec->cluster.monitorApiOnly) - { - yyerror("mark healthy/unhealthy is only allowed inside a scenario { } " - "block; use a cluster { } block for full docker compose tests"); - } - $$ = make_cmd(CMD_MARK_HEALTH); - strlcpy($$->service, $4, sizeof($$->service)); - $$->markHealthy = true; - free($4); - } - | T_MARK T_UNHEALTHY ':' T_IDENT - { - if (!current_spec->cluster.monitorApiOnly) - { - yyerror("mark healthy/unhealthy is only allowed inside a scenario { } " - "block; use a cluster { } block for full docker compose tests"); - } - $$ = make_cmd(CMD_MARK_HEALTH); - strlcpy($$->service, $4, sizeof($$->service)); - $$->markHealthy = false; - free($4); - } - ; - /* ----------------------------------------------------------------------- * sequence * ----------------------------------------------------------------------- */ diff --git a/src/bin/pgaftest/test_spec_scan.c b/src/bin/pgaftest/test_spec_scan.c index 1b5585958..09618b246 100644 --- a/src/bin/pgaftest/test_spec_scan.c +++ b/src/bin/pgaftest/test_spec_scan.c @@ -181,7 +181,7 @@ extern FILE *yyin, *yyout; *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while (0) #define unput(c) yyunput(c, (yytext_ptr)) @@ -361,8 +361,8 @@ static void yynoreturn yy_fatal_error(const char *msg); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 154 -#define YY_END_OF_BUFFER 155 +#define YY_NUM_RULES 147 +#define YY_END_OF_BUFFER 148 /* This struct is not used in this scanner, * but its presence is necessary. */ @@ -371,140 +371,137 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[1196] = +static const flex_int16_t yy_accept[1162] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 155, 19, 18, 17, 19, 1, 13, 12, 14, 14, - 14, 14, 14, 14, 16, 154, 22, 21, 154, 20, - 56, 55, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 58, 59, 96, 95, 154, 94, 127, 144, 143, 126, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 146, 147, 150, 149, 151, 152, 153, 18, 0, 15, - 1, 13, 13, 14, 14, 14, 14, 14, 14, 14, - - 14, 14, 22, 0, 57, 20, 56, 56, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 96, 0, 145, 94, 144, 144, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 118, 124, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 150, 149, 152, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 93, 93, - - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 26, 93, 93, 93, 93, 123, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 135, 148, 148, 148, - 148, 148, 148, 148, 132, 148, 148, 104, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 14, 14, 14, - 5, 14, 14, 14, 10, 14, 93, 93, 28, 93, - - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 60, 93, 93, 93, 93, - 93, 93, 31, 93, 93, 48, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 113, 148, 148, 148, - 98, 148, 148, 148, 148, 60, 148, 148, 117, 134, - 148, 139, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 115, 148, 148, - 148, 148, 100, 148, 125, 14, 14, 14, 14, 14, - 8, 14, 93, 34, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 93, 93, 93, 93, 93, 47, - 25, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 106, 148, 148, - 148, 148, 122, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 111, - 114, 119, 129, 148, 148, 148, 148, 148, 148, 101, - 148, 148, 130, 14, 14, 14, 14, 14, 14, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 38, 44, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 61, 93, 93, 93, 43, - 93, 93, 93, 93, 93, 93, 33, 148, 148, 103, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 105, 148, 148, 148, 133, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 61, 142, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 14, 14, 2, 4, 14, - 14, 14, 93, 93, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 93, 67, 93, 92, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 23, 93, 93, 93, 93, 62, 93, 93, 93, 93, - 93, 93, 42, 93, 93, 93, 93, 93, 93, 148, - 148, 148, 148, 148, 112, 110, 148, 148, 148, 67, - 148, 148, 92, 148, 148, 148, 140, 148, 148, 148, - 148, 148, 137, 108, 148, 148, 148, 148, 62, 107, - 148, 148, 148, 148, 148, 116, 131, 102, 148, 148, - 148, 148, 148, 148, 148, 14, 14, 3, 11, 9, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - - 39, 93, 93, 70, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 30, 36, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 148, 148, 148, 148, 148, 136, - 148, 148, 148, 70, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 128, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 14, - 14, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 29, 93, 40, 41, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - - 93, 93, 93, 93, 71, 93, 93, 93, 93, 93, - 93, 93, 93, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 71, 148, 148, - 141, 148, 148, 148, 148, 148, 148, 14, 14, 93, - 93, 93, 93, 93, 72, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 35, 93, 93, 93, 93, 93, 87, 86, 93, - 93, 93, 93, 93, 93, 93, 93, 148, 148, 148, - 148, 72, 148, 148, 109, 97, 148, 148, 148, 148, - - 148, 148, 148, 148, 99, 148, 148, 148, 148, 87, - 86, 148, 148, 148, 148, 148, 148, 148, 148, 14, - 14, 93, 93, 27, 54, 93, 93, 93, 32, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 77, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 77, 138, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 14, 7, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 89, 88, 24, 79, 93, 78, 93, 93, - - 93, 93, 93, 93, 93, 93, 93, 93, 64, 66, - 93, 63, 65, 148, 148, 148, 148, 148, 148, 89, - 88, 79, 148, 78, 148, 148, 148, 148, 148, 148, - 148, 148, 64, 66, 148, 63, 65, 14, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 14, 81, 80, 93, - 93, 93, 50, 69, 68, 93, 91, 90, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 81, - - 80, 120, 148, 69, 68, 91, 90, 148, 148, 148, - 148, 148, 148, 148, 148, 14, 93, 93, 45, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 14, 93, 93, 93, 37, 93, 93, 93, 93, 93, - 93, 76, 75, 85, 84, 148, 148, 148, 148, 148, - 76, 75, 85, 84, 6, 93, 93, 53, 93, 74, - 93, 73, 93, 93, 148, 148, 74, 148, 73, 46, - 49, 93, 93, 93, 51, 121, 148, 148, 83, 82, - 93, 83, 82, 52, 0 + 148, 18, 17, 16, 18, 1, 12, 11, 13, 13, + 13, 13, 13, 13, 15, 147, 21, 20, 147, 19, + 55, 54, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 57, 58, 95, 94, 147, 93, 126, 137, 125, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 139, 140, + 143, 142, 144, 145, 146, 17, 0, 14, 1, 12, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 21, + + 0, 56, 19, 55, 55, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 95, + 0, 138, 93, 137, 137, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 117, + 123, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 143, 142, 145, 13, 13, 13, 13, 13, + 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, + + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 25, 92, + 92, 92, 92, 122, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 134, 141, + 141, 141, 141, 141, 141, 141, 131, 141, 141, 103, + 141, 141, 141, 141, 141, 141, 141, 141, 13, 13, + 13, 4, 13, 13, 9, 13, 92, 92, 27, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + + 92, 92, 92, 92, 92, 59, 92, 92, 92, 92, + 92, 92, 30, 92, 92, 47, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 112, 141, 141, 141, + 97, 141, 141, 141, 59, 141, 141, 116, 133, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 114, 141, 141, 141, 99, 141, + 124, 13, 13, 13, 13, 7, 13, 92, 33, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 46, 24, 92, 92, 92, 92, + + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 105, 141, 141, 141, 141, 121, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 110, 113, 118, 128, 141, 141, 141, 141, + 141, 100, 141, 141, 129, 13, 13, 13, 13, 13, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 37, 43, 92, 92, 92, 92, + + 92, 92, 92, 92, 92, 92, 60, 92, 92, 92, + 42, 92, 92, 92, 92, 92, 92, 32, 141, 141, + 102, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 104, 141, 141, 132, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 60, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 13, 13, 2, 3, 13, 13, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 66, 92, 91, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 22, 92, 92, 92, + + 92, 61, 92, 92, 92, 92, 92, 92, 41, 92, + 92, 92, 92, 92, 92, 141, 141, 141, 141, 141, + 111, 109, 141, 141, 141, 66, 141, 141, 91, 141, + 141, 141, 141, 141, 141, 141, 141, 136, 107, 141, + 141, 141, 61, 106, 141, 141, 141, 141, 141, 115, + 130, 101, 141, 141, 141, 141, 141, 141, 13, 13, + 10, 8, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 38, 92, 92, 69, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 29, 35, 92, 92, 92, 92, 92, 92, 92, 92, + + 92, 92, 92, 92, 92, 92, 141, 141, 141, 141, + 141, 135, 141, 141, 141, 69, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 127, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 13, + 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 28, 92, 39, 40, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 70, 92, 92, 92, 92, 92, + 92, 92, 92, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + + 141, 141, 141, 141, 141, 141, 70, 141, 141, 141, + 141, 141, 141, 141, 141, 13, 13, 92, 92, 92, + 92, 92, 71, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 34, + 92, 92, 92, 92, 92, 86, 85, 92, 92, 92, + 92, 92, 92, 92, 92, 141, 141, 141, 141, 71, + 141, 141, 108, 96, 141, 141, 141, 141, 141, 141, + 141, 98, 141, 141, 141, 141, 86, 85, 141, 141, + 141, 141, 141, 141, 141, 141, 13, 13, 92, 92, + 26, 53, 92, 92, 92, 31, 92, 92, 92, 92, + + 92, 92, 92, 92, 92, 92, 92, 76, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 76, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 13, 6, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 88, 87, + 23, 78, 92, 77, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 63, 65, 92, 62, 64, 141, + 141, 141, 141, 141, 141, 88, 87, 78, 141, 77, + 141, 141, 141, 141, 141, 141, 141, 141, 63, 65, + + 141, 62, 64, 13, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 13, 80, 79, 92, 92, 92, 49, 68, + 67, 92, 90, 89, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 80, 79, 119, 141, 68, + 67, 90, 89, 141, 141, 141, 141, 141, 141, 141, + 141, 13, 92, 92, 44, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 141, 141, 141, + + 141, 141, 141, 141, 141, 141, 13, 92, 92, 92, + 36, 92, 92, 92, 92, 92, 92, 75, 74, 84, + 83, 141, 141, 141, 141, 141, 75, 74, 84, 83, + 5, 92, 92, 52, 92, 73, 92, 72, 92, 92, + 141, 141, 73, 141, 72, 45, 48, 92, 92, 92, + 50, 120, 141, 141, 82, 81, 92, 82, 81, 51, + 0 }; static const YY_CHAR yy_ec[256] = @@ -515,15 +512,15 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 8, 1, 1, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 10, 1, 1, - 11, 1, 1, 1, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 13, 12, 12, 12, 12, 12, 12, 12, - 1, 1, 1, 1, 14, 1, 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, 12, 40, 1, 41, 1, 1, 1, 1, 1, + 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, + 10, 1, 1, 1, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, + 1, 1, 1, 1, 13, 1, 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, 11, 39, 1, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -540,592 +537,575 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 }; -static const YY_CHAR yy_meta[42] = +static const YY_CHAR yy_meta[41] = { 0, 1, 2, 3, 1, 1, 1, 1, 4, 4, 1, - 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, - 1 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 }; -static const flex_int16_t yy_base[1209] = +static const flex_int16_t yy_base[1175] = { 0, - 0, 0, 41, 0, 82, 0, 122, 124, 1285, 1284, - 1286, 1289, 126, 1289, 1280, 0, 120, 1289, 0, 108, - 1255, 1254, 118, 1263, 1289, 1289, 134, 1289, 1276, 0, - 130, 1289, 0, 111, 1257, 125, 113, 1241, 127, 1246, - 122, 1248, 132, 136, 129, 142, 1257, 143, 1246, 144, - 1289, 1289, 165, 1289, 1269, 0, 1289, 159, 1289, 1289, - 0, 150, 146, 162, 150, 1258, 1240, 1252, 151, 1241, - 1246, 1239, 1252, 141, 166, 1247, 170, 177, 1237, 187, - 1289, 1289, 0, 1262, 1289, 0, 1289, 201, 1258, 1289, - 0, 198, 1289, 0, 1228, 1226, 1232, 1241, 1239, 181, - - 1238, 1241, 204, 1250, 1289, 0, 204, 1289, 0, 1224, - 1214, 1218, 1223, 186, 1216, 1220, 170, 201, 1214, 1214, - 1214, 1216, 206, 1221, 1220, 1207, 1208, 1217, 1211, 210, - 1211, 1204, 1204, 200, 1205, 1217, 1205, 1206, 1202, 1204, - 1206, 1196, 220, 1222, 1289, 0, 216, 1289, 0, 1208, - 1195, 1191, 198, 207, 1196, 1189, 1184, 212, 1188, 217, - 1186, 1189, 1202, 215, 0, 1193, 1189, 1193, 219, 1179, - 222, 1198, 1178, 225, 1180, 226, 1181, 1189, 1181, 230, - 1174, 1178, 224, 1181, 1180, 1168, 0, 1199, 0, 1165, - 1166, 1175, 1178, 1168, 1160, 1159, 1163, 1160, 1165, 1162, - - 1167, 1170, 1169, 1169, 1150, 1152, 1160, 1163, 1152, 1157, - 1149, 1159, 1143, 1149, 1140, 1153, 1154, 1138, 1143, 1142, - 1135, 1140, 1144, 1139, 1146, 1156, 1130, 1128, 1131, 1133, - 226, 1130, 1137, 0, 1127, 1121, 1121, 1129, 0, 1127, - 238, 1134, 1134, 1120, 234, 1120, 1131, 1119, 1123, 1115, - 1115, 1126, 1123, 1107, 1105, 1113, 1104, 1118, 1108, 1109, - 1101, 1105, 1107, 1114, 1093, 1110, 0, 1113, 1093, 1096, - 1098, 1097, 1094, 1093, 0, 1100, 1101, 0, 231, 1089, - 1089, 1098, 1097, 1092, 1080, 1087, 1090, 1078, 1076, 1075, - 0, 1093, 1088, 1076, 0, 1087, 1065, 1086, 1094, 1093, - - 1077, 1077, 1065, 1079, 1081, 1063, 1060, 1065, 1062, 1063, - 258, 1075, 1059, 1069, 1069, 1063, 259, 1068, 1065, 1049, - 1048, 1052, 0, 1047, 1042, 0, 1063, 1062, 1053, 1043, - 1046, 1047, 261, 1045, 263, 1052, 1031, 1037, 1047, 1044, - 1044, 1036, 1045, 1048, 1028, 1032, 0, 1032, 1029, 1026, - 1049, 1039, 266, 1025, 1020, 0, 1036, 268, 0, 0, - 1018, 0, 1029, 1021, 1035, 1013, 1026, 1031, 1030, 1015, - 1011, 1014, 1015, 1010, 1005, 1019, 1004, 270, 1001, 1006, - 1019, 1007, 271, 1013, 0, 1023, 1011, 1000, 996, 999, - 0, 997, 273, 0, 998, 991, 1005, 999, 1013, 997, - - 991, 986, 998, 993, 996, 981, 993, 992, 977, 0, - 1002, 986, 993, 253, 259, 985, 978, 986, 975, 975, - 963, 972, 968, 967, 981, 963, 978, 976, 962, 961, - 973, 972, 263, 268, 958, 280, 955, 960, 969, 963, - 952, 967, 960, 963, 953, 957, 960, 0, 958, 943, - 956, 955, 0, 952, 939, 269, 273, 953, 952, 938, - 954, 934, 935, 934, 933, 930, 929, 944, 942, 0, - 0, 927, 0, 927, 926, 938, 935, 920, 928, 0, - 277, 278, 0, 280, 921, 920, 928, 933, 912, 915, - 914, 927, 916, 929, 915, 292, 914, 933, 921, 304, - - 911, 920, 914, 907, 906, 911, 899, 917, 905, 898, - 910, 896, 908, 0, 0, 898, 893, 901, 895, 890, - 902, 881, 904, 305, 903, 0, 898, 897, 897, 0, - 899, 881, 878, 896, 878, 875, 0, 875, 874, 0, - 887, 890, 876, 884, 868, 873, 306, 872, 871, 880, - 882, 0, 867, 866, 855, 0, 861, 873, 859, 871, - 861, 855, 862, 869, 856, 865, 864, 843, 862, 307, - 865, 0, 0, 860, 859, 859, 854, 841, 840, 858, - 840, 837, 855, 837, 834, 838, 837, 0, 0, 836, - 845, 835, 843, 842, 826, 824, 824, 836, 830, 836, - - 839, 836, 834, 817, 816, 0, 828, 0, 819, 815, - 814, 816, 829, 809, 816, 818, 823, 816, 821, 822, - 828, 801, 817, 815, 315, 0, 798, 805, 804, 797, - 798, 797, 0, 803, 802, 809, 800, 799, 806, 801, - 800, 800, 783, 795, 0, 0, 782, 780, 779, 0, - 793, 790, 0, 787, 777, 776, 0, 784, 789, 782, - 787, 788, 0, 0, 768, 784, 767, 318, 0, 0, - 773, 772, 765, 766, 765, 0, 0, 0, 772, 770, - 768, 772, 763, 227, 249, 287, 295, 0, 0, 0, - 294, 296, 309, 301, 315, 300, 301, 320, 304, 313, - - 0, 317, 318, 0, 314, 306, 307, 317, 314, 328, - 309, 322, 321, 324, 323, 325, 324, 326, 0, 0, - 329, 330, 335, 328, 329, 324, 338, 339, 338, 340, - 340, 341, 343, 343, 338, 339, 366, 356, 341, 0, - 354, 355, 362, 0, 354, 344, 345, 356, 355, 358, - 357, 359, 365, 355, 0, 363, 364, 359, 362, 357, - 371, 372, 360, 372, 374, 374, 375, 377, 377, 374, - 382, 374, 375, 381, 394, 404, 383, 381, 386, 387, - 382, 391, 392, 412, 406, 407, 0, 402, 0, 0, - 409, 397, 411, 399, 411, 414, 398, 416, 400, 418, - - 402, 406, 408, 409, 0, 415, 416, 406, 426, 424, - 409, 429, 427, 412, 413, 415, 441, 420, 424, 425, - 419, 421, 440, 441, 442, 430, 444, 432, 444, 426, - 437, 449, 433, 451, 435, 440, 441, 0, 447, 448, - 0, 438, 458, 456, 441, 461, 459, 460, 460, 457, - 458, 464, 464, 454, 0, 451, 458, 455, 455, 470, - 471, 455, 460, 461, 475, 463, 478, 465, 480, 480, - 467, 0, 478, 473, 480, 475, 477, 0, 0, 489, - 490, 489, 477, 494, 492, 480, 497, 491, 492, 482, - 487, 0, 499, 500, 0, 0, 488, 489, 490, 505, - - 492, 507, 507, 508, 0, 505, 500, 507, 502, 0, - 0, 515, 516, 515, 503, 520, 518, 506, 523, 517, - 509, 514, 515, 0, 0, 512, 526, 528, 0, 513, - 519, 520, 531, 533, 534, 519, 515, 540, 517, 542, - 0, 525, 531, 533, 533, 535, 555, 549, 550, 538, - 528, 529, 541, 531, 532, 544, 545, 559, 543, 547, - 548, 560, 561, 541, 566, 543, 568, 0, 0, 556, - 558, 558, 560, 573, 574, 562, 552, 553, 565, 555, - 556, 568, 0, 576, 577, 576, 568, 586, 583, 568, - 569, 573, 0, 0, 0, 0, 574, 0, 575, 571, - - 575, 581, 577, 583, 583, 581, 582, 602, 0, 0, - 603, 0, 0, 598, 599, 587, 599, 588, 589, 0, - 0, 0, 593, 0, 594, 593, 599, 595, 601, 597, - 598, 618, 0, 0, 619, 0, 0, 620, 603, 604, - 609, 631, 608, 609, 608, 609, 611, 606, 607, 618, - 629, 615, 631, 617, 637, 618, 631, 632, 628, 629, - 625, 626, 641, 632, 628, 629, 625, 626, 647, 633, - 649, 635, 647, 648, 644, 645, 640, 0, 0, 643, - 648, 638, 0, 0, 0, 655, 0, 0, 647, 652, - 658, 654, 660, 651, 656, 657, 658, 671, 672, 0, - - 0, 0, 658, 0, 0, 0, 0, 663, 669, 665, - 671, 666, 667, 680, 681, 670, 677, 686, 0, 673, - 685, 689, 676, 691, 678, 675, 677, 682, 683, 693, - 694, 691, 700, 687, 702, 689, 691, 692, 702, 703, - 691, 690, 698, 698, 0, 699, 700, 701, 702, 694, - 697, 0, 0, 0, 0, 699, 706, 707, 708, 709, - 0, 0, 0, 0, 0, 699, 720, 0, 723, 0, - 724, 0, 713, 716, 705, 728, 0, 729, 0, 0, - 0, 728, 729, 717, 0, 0, 731, 732, 0, 0, - 734, 0, 0, 0, 1289, 752, 756, 760, 764, 763, - - 768, 772, 771, 776, 780, 779, 784, 788 + 0, 0, 40, 0, 80, 0, 119, 121, 1250, 1249, + 1251, 1254, 123, 1254, 1245, 0, 117, 1254, 0, 106, + 1221, 1220, 112, 1229, 1254, 1254, 130, 1254, 1241, 0, + 124, 1254, 0, 106, 1223, 125, 119, 1207, 127, 1212, + 116, 1214, 130, 132, 120, 137, 1223, 139, 1212, 145, + 1254, 1254, 160, 1254, 1234, 0, 1254, 154, 1254, 0, + 147, 153, 160, 138, 1224, 1206, 153, 1208, 1213, 1206, + 1219, 159, 164, 1214, 171, 176, 1204, 185, 1254, 1254, + 0, 1228, 1254, 0, 1254, 198, 1224, 1254, 0, 196, + 1254, 0, 1195, 1193, 1199, 1208, 179, 1206, 1209, 209, + + 1217, 1254, 0, 205, 1254, 0, 1192, 1182, 1186, 1191, + 183, 1184, 1188, 200, 204, 1182, 1182, 1182, 1184, 144, + 1189, 1188, 1175, 1176, 1185, 1179, 186, 1179, 1172, 1172, + 202, 1173, 1185, 1173, 1174, 1170, 1172, 1174, 1164, 219, + 1189, 1254, 0, 213, 1254, 0, 1176, 1163, 1159, 200, + 203, 1164, 1157, 1152, 220, 1156, 213, 1154, 1157, 213, + 0, 1162, 1158, 1162, 216, 1148, 1147, 1166, 1146, 222, + 1148, 223, 1149, 1157, 1149, 227, 1142, 1146, 1138, 1148, + 1147, 1135, 0, 1165, 0, 1132, 1133, 1142, 1145, 1128, + 1127, 1131, 1128, 1133, 1130, 1135, 1138, 1137, 1137, 1118, + + 1120, 1128, 1131, 1120, 1125, 1117, 1127, 1111, 1117, 1108, + 1121, 1122, 1106, 1111, 1110, 1103, 1108, 1112, 1107, 1114, + 1123, 1098, 1096, 1099, 1101, 218, 1098, 1105, 0, 1095, + 1089, 1089, 1097, 0, 1095, 229, 1102, 1102, 1088, 225, + 1088, 1099, 1087, 1091, 1083, 1083, 1094, 1091, 1075, 1073, + 1073, 1087, 1077, 1078, 1070, 1074, 1084, 1063, 0, 1084, + 1064, 1067, 1069, 1068, 1065, 1064, 0, 1071, 1072, 0, + 226, 1060, 1060, 1069, 1064, 1052, 1059, 1062, 1050, 1048, + 1047, 0, 1061, 1049, 0, 1060, 1038, 1059, 1066, 1065, + 1050, 1050, 1038, 1052, 1054, 1036, 1033, 1038, 1035, 1036, + + 252, 1048, 1032, 1042, 1042, 1036, 253, 1041, 1038, 1022, + 1021, 1025, 0, 1020, 1015, 0, 1036, 1035, 1026, 1016, + 1019, 1020, 254, 1018, 255, 1025, 1004, 1010, 1020, 1017, + 1017, 1009, 1018, 1021, 1001, 1005, 0, 1005, 1002, 999, + 1021, 1012, 261, 998, 0, 1010, 262, 0, 0, 992, + 1003, 995, 988, 1001, 1006, 1005, 990, 986, 989, 990, + 985, 980, 994, 979, 263, 976, 981, 983, 264, 989, + 0, 998, 987, 976, 976, 0, 974, 265, 0, 975, + 968, 982, 976, 989, 974, 968, 963, 975, 970, 973, + 958, 970, 969, 954, 0, 978, 963, 970, 250, 252, + + 962, 955, 963, 952, 952, 940, 949, 945, 944, 958, + 940, 955, 953, 939, 938, 950, 949, 259, 261, 935, + 281, 932, 937, 946, 940, 929, 944, 937, 940, 930, + 934, 937, 0, 935, 920, 933, 932, 0, 917, 266, + 267, 931, 930, 916, 913, 914, 913, 912, 909, 908, + 923, 921, 0, 0, 0, 0, 907, 906, 918, 915, + 900, 0, 271, 275, 0, 270, 902, 901, 915, 894, + 897, 896, 909, 898, 911, 897, 286, 896, 914, 903, + 297, 893, 902, 896, 889, 888, 893, 881, 899, 887, + 880, 892, 878, 890, 0, 0, 880, 875, 883, 877, + + 872, 884, 863, 886, 300, 885, 0, 880, 879, 879, + 0, 881, 863, 860, 878, 860, 857, 0, 857, 856, + 0, 869, 872, 858, 866, 850, 855, 303, 854, 853, + 862, 864, 0, 849, 848, 0, 844, 856, 842, 854, + 844, 838, 845, 840, 849, 848, 827, 846, 304, 849, + 0, 844, 843, 843, 838, 825, 843, 825, 822, 840, + 822, 819, 823, 822, 0, 0, 831, 821, 829, 828, + 812, 810, 810, 822, 816, 822, 825, 822, 820, 803, + 802, 0, 814, 0, 805, 801, 800, 802, 815, 795, + 802, 804, 809, 802, 807, 808, 813, 787, 803, 801, + + 311, 0, 784, 791, 790, 783, 784, 783, 0, 789, + 788, 795, 786, 785, 792, 787, 786, 786, 769, 781, + 0, 0, 768, 766, 765, 0, 779, 776, 0, 773, + 763, 762, 770, 775, 768, 773, 774, 0, 0, 771, + 754, 313, 0, 0, 760, 759, 752, 753, 752, 0, + 0, 0, 758, 757, 764, 755, 754, 761, 746, 742, + 0, 0, 739, 738, 749, 738, 750, 733, 732, 749, + 731, 738, 0, 740, 739, 0, 733, 723, 722, 729, + 721, 733, 145, 164, 225, 228, 252, 282, 286, 294, + 0, 0, 299, 301, 301, 297, 299, 294, 308, 309, + + 308, 310, 310, 311, 313, 313, 308, 309, 335, 326, + 311, 0, 324, 325, 332, 0, 324, 314, 315, 326, + 325, 328, 327, 329, 324, 0, 332, 333, 328, 331, + 326, 340, 341, 340, 342, 342, 343, 345, 345, 342, + 350, 342, 343, 349, 362, 371, 351, 349, 354, 355, + 350, 359, 360, 379, 374, 375, 0, 370, 0, 0, + 377, 365, 379, 367, 379, 382, 366, 384, 368, 386, + 370, 374, 376, 377, 0, 383, 384, 374, 394, 392, + 377, 397, 395, 380, 381, 383, 408, 388, 392, 393, + 387, 389, 408, 409, 410, 398, 412, 400, 412, 404, + + 416, 400, 418, 402, 407, 408, 0, 414, 415, 405, + 425, 423, 408, 428, 426, 427, 427, 424, 425, 431, + 431, 421, 0, 418, 425, 422, 422, 437, 438, 422, + 427, 428, 442, 430, 445, 432, 447, 447, 434, 0, + 445, 440, 447, 442, 444, 0, 0, 456, 457, 456, + 444, 461, 459, 447, 464, 458, 459, 449, 454, 0, + 466, 467, 0, 0, 455, 456, 457, 472, 459, 474, + 474, 0, 471, 466, 473, 468, 0, 0, 481, 482, + 481, 469, 486, 484, 472, 489, 483, 475, 480, 481, + 0, 0, 478, 492, 494, 0, 479, 485, 486, 497, + + 499, 500, 485, 481, 506, 483, 508, 0, 491, 497, + 499, 499, 501, 520, 515, 516, 504, 494, 495, 507, + 497, 498, 510, 511, 525, 509, 513, 514, 526, 527, + 507, 532, 509, 534, 0, 522, 524, 524, 526, 539, + 540, 528, 518, 519, 531, 521, 522, 534, 0, 542, + 543, 542, 534, 552, 549, 534, 535, 539, 0, 0, + 0, 0, 540, 0, 541, 537, 541, 547, 543, 549, + 549, 547, 548, 568, 0, 0, 569, 0, 0, 564, + 565, 553, 565, 554, 555, 0, 0, 0, 559, 0, + 560, 559, 565, 561, 567, 563, 564, 584, 0, 0, + + 585, 0, 0, 586, 569, 570, 575, 596, 574, 575, + 574, 575, 577, 572, 573, 584, 595, 581, 597, 583, + 603, 584, 597, 598, 594, 595, 591, 592, 607, 598, + 594, 595, 591, 592, 613, 599, 615, 601, 613, 614, + 610, 611, 606, 0, 0, 609, 614, 604, 0, 0, + 0, 621, 0, 0, 613, 618, 624, 620, 626, 617, + 622, 623, 624, 637, 638, 0, 0, 0, 624, 0, + 0, 0, 0, 629, 635, 631, 637, 632, 633, 646, + 647, 636, 643, 652, 0, 639, 651, 655, 642, 657, + 644, 641, 643, 648, 649, 659, 660, 657, 666, 653, + + 668, 655, 657, 658, 668, 669, 657, 656, 664, 664, + 0, 665, 666, 667, 668, 660, 663, 0, 0, 0, + 0, 665, 672, 673, 674, 675, 0, 0, 0, 0, + 0, 665, 686, 0, 689, 0, 690, 0, 679, 682, + 671, 694, 0, 695, 0, 0, 0, 694, 695, 683, + 0, 0, 697, 698, 0, 0, 700, 0, 0, 0, + 1254, 717, 721, 725, 729, 728, 733, 737, 736, 741, + 745, 744, 749, 753 }; -static const flex_int16_t yy_def[1209] = +static const flex_int16_t yy_def[1175] = { 0, - 1195, 1, 1195, 3, 1195, 5, 1196, 1196, 1197, 1197, - 1195, 1195, 1195, 1195, 1198, 1199, 1195, 1195, 1200, 1200, - 1200, 1200, 1200, 1200, 1195, 1195, 1195, 1195, 1201, 1202, - 1195, 1195, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1195, 1195, 1195, 1195, 1204, 1205, 1195, 1195, 1195, 1195, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1195, 1195, 1207, 1195, 1195, 1208, 1195, 1195, 1198, 1195, - 1199, 1195, 1195, 1200, 1200, 1200, 1200, 1200, 1200, 1200, - - 1200, 1200, 1195, 1201, 1195, 1202, 1195, 1195, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1195, 1204, 1195, 1205, 1195, 1195, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1195, 1208, 1200, - 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, - 1200, 1200, 1200, 1200, 1200, 1200, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, - 1200, 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, 1200, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, - 1200, 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1200, 1200, 1200, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, - 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1200, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, - 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1200, 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1206, 1200, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1206, - - 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1206, 1200, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, - 1200, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, - 1206, 1206, 1206, 1206, 1200, 1203, 1203, 1203, 1203, 1203, - 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1206, 1206, 1203, - 1203, 1203, 1203, 1203, 1203, 1206, 1206, 1206, 1203, 1203, - 1203, 1206, 1206, 1203, 0, 1195, 1195, 1195, 1195, 1195, - - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195 + 1161, 1, 1161, 3, 1161, 5, 1162, 1162, 1163, 1163, + 1161, 1161, 1161, 1161, 1164, 1165, 1161, 1161, 1166, 1166, + 1166, 1166, 1166, 1166, 1161, 1161, 1161, 1161, 1167, 1168, + 1161, 1161, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1161, 1161, 1161, 1161, 1170, 1171, 1161, 1161, 1161, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1161, 1161, + 1173, 1161, 1161, 1174, 1161, 1161, 1164, 1161, 1165, 1161, + 1161, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1161, + + 1167, 1161, 1168, 1161, 1161, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1161, + 1170, 1161, 1171, 1161, 1161, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1173, 1161, 1174, 1166, 1166, 1166, 1166, 1166, + 1166, 1166, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, + 1166, 1166, 1166, 1166, 1166, 1166, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1166, 1166, 1166, 1166, 1166, 1166, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1166, 1166, 1166, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1166, 1166, 1166, 1166, 1166, 1166, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, + 1166, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, + 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1166, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + + 1172, 1172, 1172, 1166, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, 1172, 1172, + 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1172, 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1172, 1172, 1172, + + 1172, 1172, 1172, 1172, 1172, 1172, 1166, 1169, 1169, 1169, + 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1169, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, + 1166, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1172, 1172, 1172, 1172, 1172, 1169, 1169, 1169, 1169, 1169, + 1169, 1172, 1172, 1172, 1169, 1169, 1169, 1172, 1172, 1169, + 0, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161 }; -static const flex_int16_t yy_nxt[1331] = +static const flex_int16_t yy_nxt[1295] = { 0, - 12, 13, 14, 13, 15, 16, 12, 12, 17, 12, - 18, 19, 19, 19, 19, 19, 20, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 21, 22, 19, 19, - 19, 19, 23, 24, 19, 19, 19, 19, 19, 25, - 12, 26, 27, 28, 27, 29, 30, 26, 26, 31, - 26, 32, 33, 33, 33, 34, 35, 36, 37, 38, - 39, 40, 33, 41, 42, 33, 43, 44, 45, 33, - 46, 33, 47, 48, 33, 33, 49, 50, 33, 33, - 51, 52, 26, 53, 54, 53, 55, 56, 57, 26, - 58, 59, 60, 61, 61, 61, 62, 61, 63, 64, - - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 61, 75, 61, 76, 77, 78, 79, 61, 80, 61, - 61, 81, 82, 84, 85, 84, 85, 88, 92, 88, - 95, 117, 93, 96, 99, 103, 100, 103, 107, 114, - 110, 120, 108, 111, 118, 112, 126, 115, 123, 124, - 128, 101, 93, 116, 127, 121, 132, 130, 141, 170, - 153, 136, 108, 131, 129, 137, 143, 147, 143, 171, - 133, 148, 142, 134, 154, 138, 139, 150, 164, 151, - 155, 159, 152, 165, 156, 207, 172, 160, 176, 208, - 157, 148, 177, 158, 173, 178, 209, 174, 181, 182, - - 179, 184, 88, 180, 88, 103, 92, 103, 185, 186, - 93, 195, 107, 203, 196, 210, 108, 224, 229, 204, - 216, 143, 230, 143, 147, 242, 249, 225, 148, 211, - 93, 243, 217, 244, 245, 252, 108, 257, 258, 266, - 250, 262, 274, 270, 279, 283, 253, 271, 148, 768, - 263, 329, 264, 272, 330, 267, 338, 284, 280, 275, - 339, 343, 375, 769, 376, 407, 414, 344, 429, 377, - 433, 408, 415, 451, 430, 456, 434, 474, 481, 452, - 490, 457, 510, 475, 482, 511, 491, 538, 512, 531, - 431, 513, 532, 539, 534, 533, 586, 535, 557, 476, - - 536, 558, 559, 580, 583, 560, 581, 584, 599, 582, - 585, 604, 628, 648, 671, 770, 587, 605, 629, 649, - 672, 606, 721, 650, 600, 756, 771, 772, 722, 773, - 774, 757, 775, 776, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, - 793, 794, 795, 796, 797, 798, 800, 802, 799, 801, - 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, - 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, - 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, - 834, 836, 833, 835, 837, 838, 839, 840, 841, 842, - - 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, - 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, - 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, - 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, - 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, - 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, - 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, - 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, - 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, - 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, - - 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, - 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, - 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, - 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, - 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, - 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, - 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, - 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, - 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, - 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, - 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, - 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, - 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, - 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, - 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, - 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, - - 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, - 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, - 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, - 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, - 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, - 1193, 1194, 83, 83, 83, 83, 86, 86, 86, 86, - 89, 89, 89, 89, 91, 91, 94, 91, 104, 104, - 104, 104, 106, 106, 109, 106, 144, 144, 144, 144, - 146, 146, 149, 146, 187, 767, 766, 187, 189, 189, - 765, 189, 764, 763, 762, 761, 760, 759, 758, 755, - - 754, 753, 752, 751, 750, 749, 748, 747, 746, 745, - 744, 743, 742, 741, 740, 739, 738, 737, 736, 735, - 734, 733, 732, 731, 730, 729, 728, 727, 726, 725, - 724, 723, 720, 719, 718, 717, 716, 715, 714, 713, - 712, 711, 710, 709, 708, 707, 706, 705, 704, 703, - 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, - 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, - 682, 681, 680, 679, 678, 677, 676, 675, 674, 673, - 670, 669, 668, 667, 666, 665, 664, 663, 662, 661, - 660, 659, 658, 657, 656, 655, 654, 653, 652, 651, - - 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, - 637, 636, 635, 634, 633, 632, 631, 630, 627, 626, - 625, 624, 623, 622, 621, 620, 619, 618, 617, 616, - 615, 614, 613, 612, 611, 610, 609, 608, 607, 603, - 602, 601, 598, 597, 596, 595, 594, 593, 592, 591, - 590, 589, 588, 579, 578, 577, 576, 575, 574, 573, - 572, 571, 570, 569, 568, 567, 566, 565, 564, 563, - 562, 561, 556, 555, 554, 553, 552, 551, 550, 549, - 548, 547, 546, 545, 544, 543, 542, 541, 540, 537, - 530, 529, 528, 527, 526, 525, 524, 523, 522, 521, - - 520, 519, 518, 517, 516, 515, 514, 509, 508, 507, - 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, - 496, 495, 494, 493, 492, 489, 488, 487, 486, 485, - 484, 483, 480, 479, 478, 477, 473, 472, 471, 470, - 469, 468, 467, 466, 465, 464, 463, 462, 461, 460, - 459, 458, 455, 454, 453, 450, 449, 448, 447, 446, - 445, 444, 443, 442, 441, 440, 439, 438, 437, 436, - 435, 432, 428, 427, 426, 425, 424, 423, 422, 421, - 420, 419, 418, 417, 416, 413, 412, 411, 410, 409, - 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, - - 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, - 386, 385, 384, 383, 382, 381, 380, 379, 378, 374, - 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, - 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, - 353, 352, 351, 350, 349, 348, 347, 346, 345, 342, - 341, 340, 337, 336, 335, 334, 333, 332, 331, 328, - 327, 326, 325, 324, 323, 322, 321, 320, 319, 318, - 317, 316, 315, 314, 313, 312, 311, 310, 309, 308, - 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, - 297, 296, 295, 294, 293, 292, 291, 290, 289, 288, - - 188, 287, 286, 285, 282, 281, 278, 277, 276, 273, - 269, 268, 265, 261, 260, 259, 256, 255, 254, 251, - 248, 247, 246, 241, 240, 239, 145, 238, 237, 236, - 235, 234, 233, 232, 231, 228, 227, 226, 223, 222, - 221, 220, 219, 218, 215, 214, 213, 212, 206, 205, - 202, 201, 200, 199, 105, 198, 197, 194, 193, 192, - 191, 190, 90, 188, 183, 175, 169, 168, 167, 166, - 163, 162, 161, 145, 140, 135, 125, 122, 119, 113, - 105, 102, 98, 97, 90, 1195, 87, 87, 11, 1195, - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, - - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195 + 12, 13, 14, 13, 15, 16, 12, 12, 17, 18, + 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 21, 22, 19, 19, 19, + 19, 23, 24, 19, 19, 19, 19, 19, 25, 12, + 26, 27, 28, 27, 29, 30, 26, 26, 31, 32, + 33, 33, 33, 34, 35, 36, 37, 38, 39, 40, + 33, 41, 42, 33, 43, 44, 45, 33, 46, 33, + 47, 48, 33, 33, 49, 50, 33, 33, 51, 52, + 26, 53, 54, 53, 55, 56, 57, 26, 58, 59, + 60, 60, 60, 61, 60, 62, 63, 64, 65, 66, + + 60, 67, 68, 69, 70, 71, 72, 60, 73, 60, + 74, 75, 76, 77, 60, 78, 60, 60, 79, 80, + 82, 83, 82, 83, 86, 90, 86, 93, 91, 97, + 94, 100, 104, 100, 107, 105, 114, 108, 111, 109, + 117, 120, 121, 123, 98, 125, 112, 127, 91, 115, + 129, 124, 113, 128, 118, 105, 133, 211, 138, 126, + 134, 140, 144, 140, 130, 145, 150, 131, 156, 212, + 135, 136, 139, 147, 157, 148, 166, 152, 149, 160, + 151, 153, 760, 168, 161, 145, 167, 154, 172, 761, + 155, 169, 173, 219, 170, 174, 177, 178, 180, 86, + + 175, 86, 220, 176, 90, 181, 182, 91, 190, 198, + 100, 191, 100, 104, 202, 199, 105, 205, 203, 224, + 140, 144, 140, 225, 145, 204, 237, 91, 239, 240, + 247, 206, 238, 244, 251, 252, 105, 256, 266, 262, + 271, 248, 319, 263, 145, 320, 328, 245, 257, 264, + 329, 333, 762, 763, 272, 267, 362, 334, 363, 392, + 399, 414, 418, 364, 393, 400, 415, 419, 436, 440, + 457, 463, 471, 437, 441, 458, 464, 472, 491, 764, + 493, 492, 416, 494, 512, 563, 515, 513, 519, 516, + 514, 459, 517, 520, 537, 539, 557, 538, 540, 558, + + 560, 575, 559, 561, 580, 564, 562, 604, 765, 581, + 624, 645, 605, 582, 766, 625, 646, 576, 693, 626, + 727, 767, 772, 694, 768, 728, 770, 769, 773, 771, + 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, + 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, + 794, 795, 796, 797, 798, 799, 800, 801, 803, 805, + 802, 804, 806, 807, 808, 809, 810, 811, 812, 813, + 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, + 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, + 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, + + 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, + 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, + 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, + 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, + 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, + 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, + 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, + 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, + 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, + 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, + + 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, + 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, + 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, + 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, + 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, + 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, + 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, + 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, + 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, + 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, + 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, + 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, + 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, + 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, + 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, + + 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, + 1154, 1155, 1156, 1157, 1158, 1159, 1160, 81, 81, 81, + 81, 84, 84, 84, 84, 87, 87, 87, 87, 89, + 89, 92, 89, 101, 101, 101, 101, 103, 103, 106, + 103, 141, 141, 141, 141, 143, 143, 146, 143, 183, + 759, 758, 183, 185, 185, 757, 185, 756, 755, 754, + 753, 752, 751, 750, 749, 748, 747, 746, 745, 744, + 743, 742, 741, 740, 739, 738, 737, 736, 735, 734, + 733, 732, 731, 730, 729, 726, 725, 724, 723, 722, + 721, 720, 719, 718, 717, 716, 715, 714, 713, 712, + + 711, 710, 709, 708, 707, 706, 705, 704, 703, 702, + 701, 700, 699, 698, 697, 696, 695, 692, 691, 690, + 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, + 679, 678, 677, 676, 675, 674, 673, 672, 671, 670, + 669, 668, 667, 666, 665, 664, 663, 662, 661, 660, + 659, 658, 657, 656, 655, 654, 653, 652, 651, 650, + 649, 648, 647, 644, 643, 642, 641, 640, 639, 638, + 637, 636, 635, 634, 633, 632, 631, 630, 629, 628, + 627, 623, 622, 621, 620, 619, 618, 617, 616, 615, + 614, 613, 612, 611, 610, 609, 608, 607, 606, 603, + + 602, 601, 600, 599, 598, 597, 596, 595, 594, 593, + 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, + 579, 578, 577, 574, 573, 572, 571, 570, 569, 568, + 567, 566, 565, 556, 555, 554, 553, 552, 551, 550, + 549, 548, 547, 546, 545, 544, 543, 542, 541, 536, + 535, 534, 533, 532, 531, 530, 529, 528, 527, 526, + 525, 524, 523, 522, 521, 518, 511, 510, 509, 508, + 507, 506, 505, 504, 503, 502, 501, 500, 499, 498, + 497, 496, 495, 490, 489, 488, 487, 486, 485, 484, + 483, 482, 481, 480, 479, 478, 477, 476, 475, 474, + + 473, 470, 469, 468, 467, 466, 465, 462, 461, 460, + 456, 455, 454, 453, 452, 451, 450, 449, 448, 447, + 446, 445, 444, 443, 442, 439, 438, 435, 434, 433, + 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, + 422, 421, 420, 417, 413, 412, 411, 410, 409, 408, + 407, 406, 405, 404, 403, 402, 401, 398, 397, 396, + 395, 394, 391, 390, 389, 388, 387, 386, 385, 384, + 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, + 373, 372, 371, 370, 369, 368, 367, 366, 365, 361, + 360, 359, 358, 357, 356, 355, 354, 353, 352, 351, + + 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, + 340, 339, 338, 337, 336, 335, 332, 331, 330, 327, + 326, 325, 324, 323, 322, 321, 318, 317, 316, 315, + 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, + 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, + 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, + 284, 283, 282, 281, 280, 279, 184, 278, 277, 276, + 275, 274, 273, 270, 269, 268, 265, 261, 260, 259, + 258, 255, 254, 253, 250, 249, 246, 243, 242, 241, + 236, 235, 234, 142, 233, 232, 231, 230, 229, 228, + + 227, 226, 223, 222, 221, 218, 217, 216, 215, 214, + 213, 210, 209, 208, 207, 201, 200, 197, 196, 195, + 194, 102, 193, 192, 189, 188, 187, 186, 88, 184, + 179, 171, 165, 164, 163, 162, 159, 158, 142, 137, + 132, 122, 119, 116, 110, 102, 99, 96, 95, 88, + 1161, 85, 85, 11, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161 }; -static const flex_int16_t yy_chk[1331] = +static const flex_int16_t yy_chk[1295] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 7, 7, 8, 8, 13, 17, 13, - 20, 37, 17, 20, 23, 27, 23, 27, 31, 36, - 34, 39, 31, 34, 37, 34, 43, 36, 41, 41, - 44, 23, 17, 36, 43, 39, 46, 45, 50, 74, - 63, 48, 31, 45, 44, 48, 53, 58, 53, 74, - 46, 58, 50, 46, 63, 48, 48, 62, 69, 62, - 64, 65, 62, 69, 64, 117, 75, 65, 77, 117, - 64, 58, 77, 64, 75, 77, 117, 75, 78, 78, - - 77, 80, 88, 77, 88, 103, 92, 103, 80, 80, - 92, 100, 107, 114, 100, 118, 107, 130, 134, 114, - 123, 143, 134, 143, 147, 153, 158, 130, 147, 118, - 92, 153, 123, 154, 154, 160, 107, 164, 164, 171, - 158, 169, 176, 174, 180, 183, 160, 174, 147, 684, - 169, 231, 169, 174, 231, 171, 241, 183, 180, 176, - 241, 245, 279, 685, 279, 311, 317, 245, 333, 279, - 335, 311, 317, 353, 333, 358, 335, 378, 383, 353, - 393, 358, 414, 378, 383, 414, 393, 436, 415, 433, - 333, 415, 433, 436, 434, 433, 484, 434, 456, 378, - - 434, 456, 457, 481, 482, 457, 481, 482, 496, 481, - 482, 500, 524, 547, 570, 686, 484, 500, 524, 547, - 570, 500, 625, 547, 496, 668, 687, 691, 625, 692, - 693, 668, 694, 695, 696, 697, 698, 699, 700, 702, - 703, 705, 706, 707, 708, 709, 710, 711, 712, 713, - 714, 715, 716, 717, 718, 721, 722, 723, 721, 722, - 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, - 734, 735, 736, 737, 738, 739, 741, 742, 743, 745, - 746, 747, 748, 749, 750, 751, 752, 753, 754, 756, - 757, 758, 756, 757, 759, 760, 761, 762, 763, 764, - - 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, - 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, - 785, 786, 788, 791, 792, 793, 794, 795, 796, 797, - 798, 799, 800, 801, 802, 803, 804, 806, 807, 808, - 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, - 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 833, 834, 835, 836, 837, 839, - 840, 842, 843, 844, 845, 846, 847, 848, 849, 850, - 851, 852, 853, 854, 856, 857, 858, 859, 860, 861, - 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, - - 873, 874, 875, 876, 877, 880, 881, 882, 883, 884, - 885, 886, 887, 888, 889, 890, 891, 893, 894, 897, - 898, 899, 900, 901, 902, 903, 904, 906, 907, 908, - 909, 912, 913, 914, 915, 916, 917, 918, 919, 920, - 921, 922, 923, 926, 927, 928, 930, 931, 932, 933, - 934, 935, 936, 937, 938, 939, 940, 942, 943, 944, - 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, - 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, - 965, 966, 967, 970, 971, 972, 973, 974, 975, 976, - 977, 978, 979, 980, 981, 982, 984, 985, 986, 987, - - 988, 989, 990, 991, 992, 997, 999, 1000, 1001, 1002, - 1003, 1004, 1005, 1005, 1006, 1007, 1008, 1011, 1014, 1015, - 1016, 1017, 1018, 1019, 1023, 1025, 1026, 1027, 1028, 1029, - 1030, 1031, 1032, 1035, 1038, 1039, 1040, 1041, 1042, 1043, - 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, - 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, - 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, - 1074, 1075, 1076, 1077, 1080, 1081, 1082, 1086, 1089, 1090, - 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1103, - 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, - - 1118, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, - 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, - 1139, 1140, 1141, 1142, 1143, 1144, 1146, 1147, 1148, 1149, - 1150, 1151, 1156, 1157, 1158, 1159, 1160, 1166, 1167, 1169, - 1171, 1173, 1174, 1175, 1176, 1178, 1182, 1183, 1184, 1187, - 1188, 1191, 1196, 1196, 1196, 1196, 1197, 1197, 1197, 1197, - 1198, 1198, 1198, 1198, 1199, 1199, 1200, 1199, 1201, 1201, - 1201, 1201, 1202, 1202, 1203, 1202, 1204, 1204, 1204, 1204, - 1205, 1205, 1206, 1205, 1207, 683, 682, 1207, 1208, 1208, - 681, 1208, 680, 679, 675, 674, 673, 672, 671, 667, - - 666, 665, 662, 661, 660, 659, 658, 656, 655, 654, - 652, 651, 649, 648, 647, 644, 643, 642, 641, 640, - 639, 638, 637, 636, 635, 634, 632, 631, 630, 629, - 628, 627, 624, 623, 622, 621, 620, 619, 618, 617, - 616, 615, 614, 613, 612, 611, 610, 609, 607, 605, - 604, 603, 602, 601, 600, 599, 598, 597, 596, 595, - 594, 593, 592, 591, 590, 587, 586, 585, 584, 583, - 582, 581, 580, 579, 578, 577, 576, 575, 574, 571, - 569, 568, 567, 566, 565, 564, 563, 562, 561, 560, - 559, 558, 557, 555, 554, 553, 551, 550, 549, 548, - - 546, 545, 544, 543, 542, 541, 539, 538, 536, 535, - 534, 533, 532, 531, 529, 528, 527, 525, 523, 522, - 521, 520, 519, 518, 517, 516, 513, 512, 511, 510, - 509, 508, 507, 506, 505, 504, 503, 502, 501, 499, - 498, 497, 495, 494, 493, 492, 491, 490, 489, 488, - 487, 486, 485, 479, 478, 477, 476, 475, 474, 472, - 469, 468, 467, 466, 465, 464, 463, 462, 461, 460, - 459, 458, 455, 454, 452, 451, 450, 449, 447, 446, - 445, 444, 443, 442, 441, 440, 439, 438, 437, 435, - 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, - - 422, 421, 420, 419, 418, 417, 416, 413, 412, 411, - 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, - 399, 398, 397, 396, 395, 392, 390, 389, 388, 387, - 386, 384, 382, 381, 380, 379, 377, 376, 375, 374, - 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, - 363, 361, 357, 355, 354, 352, 351, 350, 349, 348, - 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, - 336, 334, 332, 331, 330, 329, 328, 327, 325, 324, - 322, 321, 320, 319, 318, 316, 315, 314, 313, 312, - 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, - - 300, 299, 298, 297, 296, 294, 293, 292, 290, 289, - 288, 287, 286, 285, 284, 283, 282, 281, 280, 277, - 276, 274, 273, 272, 271, 270, 269, 268, 266, 265, - 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, - 254, 253, 252, 251, 250, 249, 248, 247, 246, 244, - 243, 242, 240, 238, 237, 236, 235, 233, 232, 230, - 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, - 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, - 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, - 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, - - 188, 186, 185, 184, 182, 181, 179, 178, 177, 175, - 173, 172, 170, 168, 167, 166, 163, 162, 161, 159, - 157, 156, 155, 152, 151, 150, 144, 142, 141, 140, - 139, 138, 137, 136, 135, 133, 132, 131, 129, 128, - 127, 126, 125, 124, 122, 121, 120, 119, 116, 115, - 113, 112, 111, 110, 104, 102, 101, 99, 98, 97, - 96, 95, 89, 84, 79, 76, 73, 72, 71, 70, - 68, 67, 66, 55, 49, 47, 42, 40, 38, 35, - 29, 24, 22, 21, 15, 11, 10, 9, 1195, 1195, - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, - - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, - 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195 + 7, 7, 8, 8, 13, 17, 13, 20, 17, 23, + 20, 27, 31, 27, 34, 31, 37, 34, 36, 34, + 39, 41, 41, 43, 23, 44, 36, 45, 17, 37, + 46, 43, 36, 45, 39, 31, 48, 120, 50, 44, + 48, 53, 58, 53, 46, 58, 62, 46, 64, 120, + 48, 48, 50, 61, 64, 61, 72, 63, 61, 67, + 62, 63, 683, 73, 67, 58, 72, 63, 75, 684, + 63, 73, 75, 127, 73, 75, 76, 76, 78, 86, + + 75, 86, 127, 75, 90, 78, 78, 90, 97, 111, + 100, 97, 100, 104, 114, 111, 104, 115, 114, 131, + 140, 144, 140, 131, 144, 114, 150, 90, 151, 151, + 157, 115, 150, 155, 160, 160, 104, 165, 172, 170, + 176, 157, 226, 170, 144, 226, 236, 155, 165, 170, + 236, 240, 685, 686, 176, 172, 271, 240, 271, 301, + 307, 323, 325, 271, 301, 307, 323, 325, 343, 347, + 365, 369, 378, 343, 347, 365, 369, 378, 399, 687, + 400, 399, 323, 400, 418, 466, 419, 418, 421, 419, + 418, 365, 419, 421, 440, 441, 463, 440, 441, 463, + + 464, 477, 463, 464, 481, 466, 464, 505, 688, 481, + 528, 549, 505, 481, 689, 528, 549, 477, 601, 528, + 642, 690, 695, 601, 693, 642, 694, 693, 696, 694, + 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, + 707, 708, 709, 710, 711, 713, 714, 715, 717, 718, + 719, 720, 721, 722, 723, 724, 725, 727, 728, 729, + 727, 728, 730, 731, 732, 733, 734, 735, 736, 737, + 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, + 748, 749, 750, 751, 752, 753, 754, 755, 756, 758, + 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, + + 771, 772, 773, 774, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, + 802, 803, 804, 805, 806, 808, 809, 810, 811, 812, + 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, + 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, + 834, 835, 836, 837, 838, 839, 841, 842, 843, 844, + 845, 848, 849, 850, 851, 852, 853, 854, 855, 856, + 857, 858, 859, 861, 862, 865, 866, 867, 868, 869, + 870, 871, 873, 874, 875, 876, 879, 880, 881, 882, + + 883, 884, 885, 886, 887, 888, 889, 890, 893, 894, + 895, 897, 898, 899, 900, 901, 902, 903, 904, 905, + 906, 907, 909, 910, 911, 912, 913, 914, 915, 916, + 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, + 927, 928, 929, 930, 931, 932, 933, 934, 936, 937, + 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, + 948, 950, 951, 952, 953, 954, 955, 956, 957, 958, + 963, 965, 966, 967, 968, 969, 970, 971, 971, 972, + 973, 974, 977, 980, 981, 982, 983, 984, 985, 989, + 991, 992, 993, 994, 995, 996, 997, 998, 1001, 1004, + + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, + 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, + 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1046, + 1047, 1048, 1052, 1055, 1056, 1057, 1058, 1059, 1060, 1061, + 1062, 1063, 1064, 1065, 1069, 1074, 1075, 1076, 1077, 1078, + 1079, 1080, 1081, 1082, 1083, 1084, 1086, 1087, 1088, 1089, + 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, + 1110, 1112, 1113, 1114, 1115, 1116, 1117, 1122, 1123, 1124, + + 1125, 1126, 1132, 1133, 1135, 1137, 1139, 1140, 1141, 1142, + 1144, 1148, 1149, 1150, 1153, 1154, 1157, 1162, 1162, 1162, + 1162, 1163, 1163, 1163, 1163, 1164, 1164, 1164, 1164, 1165, + 1165, 1166, 1165, 1167, 1167, 1167, 1167, 1168, 1168, 1169, + 1168, 1170, 1170, 1170, 1170, 1171, 1171, 1172, 1171, 1173, + 682, 681, 1173, 1174, 1174, 680, 1174, 679, 678, 677, + 675, 674, 672, 671, 670, 669, 668, 667, 666, 665, + 664, 663, 660, 659, 658, 657, 656, 655, 654, 653, + 649, 648, 647, 646, 645, 641, 640, 637, 636, 635, + 634, 633, 632, 631, 630, 628, 627, 625, 624, 623, + + 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, + 610, 608, 607, 606, 605, 604, 603, 600, 599, 598, + 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, + 587, 586, 585, 583, 581, 580, 579, 578, 577, 576, + 575, 574, 573, 572, 571, 570, 569, 568, 567, 564, + 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, + 553, 552, 550, 548, 547, 546, 545, 544, 543, 542, + 541, 540, 539, 538, 537, 535, 534, 532, 531, 530, + 529, 527, 526, 525, 524, 523, 522, 520, 519, 517, + 516, 515, 514, 513, 512, 510, 509, 508, 506, 504, + + 503, 502, 501, 500, 499, 498, 497, 494, 493, 492, + 491, 490, 489, 488, 487, 486, 485, 484, 483, 482, + 480, 479, 478, 476, 475, 474, 473, 472, 471, 470, + 469, 468, 467, 461, 460, 459, 458, 457, 452, 451, + 450, 449, 448, 447, 446, 445, 444, 443, 442, 439, + 437, 436, 435, 434, 432, 431, 430, 429, 428, 427, + 426, 425, 424, 423, 422, 420, 417, 416, 415, 414, + 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, + 403, 402, 401, 398, 397, 396, 394, 393, 392, 391, + 390, 389, 388, 387, 386, 385, 384, 383, 382, 381, + + 380, 377, 375, 374, 373, 372, 370, 368, 367, 366, + 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, + 354, 353, 352, 351, 350, 346, 344, 342, 341, 340, + 339, 338, 336, 335, 334, 333, 332, 331, 330, 329, + 328, 327, 326, 324, 322, 321, 320, 319, 318, 317, + 315, 314, 312, 311, 310, 309, 308, 306, 305, 304, + 303, 302, 300, 299, 298, 297, 296, 295, 294, 293, + 292, 291, 290, 289, 288, 287, 286, 284, 283, 281, + 280, 279, 278, 277, 276, 275, 274, 273, 272, 269, + 268, 266, 265, 264, 263, 262, 261, 260, 258, 257, + + 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, + 246, 245, 244, 243, 242, 241, 239, 238, 237, 235, + 233, 232, 231, 230, 228, 227, 225, 224, 223, 222, + 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, + 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, + 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, + 191, 190, 189, 188, 187, 186, 184, 182, 181, 180, + 179, 178, 177, 175, 174, 173, 171, 169, 168, 167, + 166, 164, 163, 162, 159, 158, 156, 154, 153, 152, + 149, 148, 147, 141, 139, 138, 137, 136, 135, 134, + + 133, 132, 130, 129, 128, 126, 125, 124, 123, 122, + 121, 119, 118, 117, 116, 113, 112, 110, 109, 108, + 107, 101, 99, 98, 96, 95, 94, 93, 87, 82, + 77, 74, 71, 70, 69, 68, 66, 65, 55, 49, + 47, 42, 40, 38, 35, 29, 24, 22, 21, 15, + 11, 10, 9, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161 }; static yy_state_type yy_last_accepting_state; @@ -1177,10 +1157,8 @@ int pgaf_line_number = 1; static int pgaf_next_brace_is_step = 0; /* - * When the lexer sees "cluster" or "scenario", it sets this flag so the - * next "{" enters CLUSTER_BODY rather than doing the raw block read. - * The CLUSTER_BODY state is reused for "scenario" since the inner syntax - * (formation, node names, ssl, auth) is identical. + * When the lexer sees "cluster", it sets this flag so the next "{" + * enters CLUSTER_BODY rather than doing the raw block read. */ static int pgaf_next_brace_is_cluster = 0; @@ -1212,7 +1190,7 @@ pgaf_strdup(const char *s) char *r = strdup(s); if (!r) { - fprintf(stderr, "out of memory\n"); + fprintf(stderr, "out of memory\n"); /* IGNORE-BANNED */ exit(1); } return r; @@ -1229,9 +1207,9 @@ pgaf_strdup(const char *s) * call flex's static input() function. */ static void pgaf_read_raw_block(void); -#line 1213 "test_spec_scan.c" +#line 1192 "test_spec_scan.c" -#line 1215 "test_spec_scan.c" +#line 1194 "test_spec_scan.c" #define INITIAL 0 #define CLUSTER_BODY 1 @@ -1358,7 +1336,8 @@ static int input(void); else \ { \ errno = 0; \ - while ((result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror( \ + while ((result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && \ + ferror( \ yyin)) \ { \ if (errno != EINTR) \ @@ -1461,10 +1440,10 @@ YY_DECL } { -#line 91 "test_spec_scan.l" +#line 89 "test_spec_scan.l" -#line 1437 "test_spec_scan.c" +#line 1416 "test_spec_scan.c" while (/*CONSTCOND*/ 1) /* loops until end-of-file is reached */ { @@ -1490,14 +1469,14 @@ YY_DECL while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { yy_current_state = (int) yy_def[yy_current_state]; - if (yy_current_state >= 1196) + if (yy_current_state >= 1162) { yy_c = yy_meta[yy_c]; } } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; - } while (yy_current_state != 1195); + } while (yy_current_state != 1161); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -1512,134 +1491,166 @@ YY_DECL { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ + { *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; + } case 1: + { YY_RULE_SETUP -#line 93 "test_spec_scan.l" +#line 91 "test_spec_scan.l" { /* comment */ } YY_BREAK + } + case 2: + { YY_RULE_SETUP -#line 95 "test_spec_scan.l" +#line 93 "test_spec_scan.l" { pgaf_next_brace_is_cluster = 1; return T_CLUSTER; } YY_BREAK - case 3: - YY_RULE_SETUP -#line 96 "test_spec_scan.l" - { - pgaf_next_brace_is_cluster = 1; - return T_SCENARIO; - } + } - YY_BREAK - case 4: + case 3: + { YY_RULE_SETUP -#line 97 "test_spec_scan.l" +#line 94 "test_spec_scan.l" { return T_MONITOR; } YY_BREAK - case 5: + } + + case 4: + { YY_RULE_SETUP -#line 98 "test_spec_scan.l" +#line 95 "test_spec_scan.l" { return T_NODE; } YY_BREAK - case 6: + } + + case 5: + { YY_RULE_SETUP -#line 99 "test_spec_scan.l" +#line 96 "test_spec_scan.l" { return T_CITUS_COORDINATOR; } YY_BREAK - case 7: + } + + case 6: + { YY_RULE_SETUP -#line 100 "test_spec_scan.l" +#line 97 "test_spec_scan.l" { return T_CITUS_WORKER; } YY_BREAK - case 8: + } + + case 7: + { YY_RULE_SETUP -#line 102 "test_spec_scan.l" +#line 99 "test_spec_scan.l" { pgaf_next_brace_is_step = 1; return T_SETUP; } YY_BREAK - case 9: + } + + case 8: + { YY_RULE_SETUP -#line 103 "test_spec_scan.l" +#line 100 "test_spec_scan.l" { pgaf_next_brace_is_step = 1; return T_TEARDOWN; } YY_BREAK - case 10: + } + + case 9: + { YY_RULE_SETUP -#line 104 "test_spec_scan.l" +#line 101 "test_spec_scan.l" { pgaf_next_brace_is_step = 1; return T_STEP; } YY_BREAK - case 11: + } + + case 10: + { YY_RULE_SETUP -#line 105 "test_spec_scan.l" +#line 102 "test_spec_scan.l" { return T_SEQUENCE; } YY_BREAK - case 12: + } + + case 11: + { YY_RULE_SETUP -#line 107 "test_spec_scan.l" +#line 104 "test_spec_scan.l" { return T_EQUALS; } YY_BREAK - case 13: + } + + case 12: + { YY_RULE_SETUP -#line 109 "test_spec_scan.l" +#line 106 "test_spec_scan.l" { - yylval.ival = atoi(yytext); + yylval.ival = atoi(yytext); /* IGNORE-BANNED */ return T_INTEGER; } YY_BREAK - case 14: + } + + case 13: + { YY_RULE_SETUP -#line 114 "test_spec_scan.l" +#line 111 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); return T_IDENT; } YY_BREAK - case 15: + } -/* rule 15 can match eol */ + case 14: + { +/* rule 14 can match eol */ YY_RULE_SETUP -#line 119 "test_spec_scan.l" +#line 116 "test_spec_scan.l" { yytext[yyleng - 1] = '\0'; yylval.str = pgaf_strdup(yytext + 1); @@ -1647,9 +1658,12 @@ YY_DECL } YY_BREAK - case 16: + } + + case 15: + { YY_RULE_SETUP -#line 125 "test_spec_scan.l" +#line 122 "test_spec_scan.l" { if (pgaf_next_brace_is_step) { @@ -1666,340 +1680,461 @@ YY_DECL } /* fallback: should not happen in a well-formed file */ - fprintf(stderr, "pgaftest: unexpected '{' at line %d\n", - pgaf_line_number); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: unexpected '{' at line %d\n", + pgaf_line_number); } YY_BREAK - case 17: + } -/* rule 17 can match eol */ + case 16: + { +/* rule 16 can match eol */ YY_RULE_SETUP -#line 143 "test_spec_scan.l" +#line 140 "test_spec_scan.l" { pgaf_line_number++; } YY_BREAK - case 18: + } + + case 17: + { YY_RULE_SETUP -#line 144 "test_spec_scan.l" +#line 141 "test_spec_scan.l" { /* whitespace */ } YY_BREAK - case 19: + } + + case 18: + { YY_RULE_SETUP -#line 146 "test_spec_scan.l" +#line 143 "test_spec_scan.l" { - fprintf(stderr, - "pgaftest: unexpected character '%c' at line %d\n", - yytext[0], pgaf_line_number); + fprintf(/* IGNORE-BANNED */ stderr, + "pgaftest: unexpected character '%c' at line %d\n", + yytext[0], pgaf_line_number); } YY_BREAK - case 20: + } + + case 19: + { YY_RULE_SETUP -#line 151 "test_spec_scan.l" +#line 148 "test_spec_scan.l" { /* comment */ } YY_BREAK - case 21: + } -/* rule 21 can match eol */ + case 20: + { +/* rule 20 can match eol */ YY_RULE_SETUP -#line 152 "test_spec_scan.l" +#line 149 "test_spec_scan.l" { pgaf_line_number++; } YY_BREAK - case 22: + } + + case 21: + { YY_RULE_SETUP -#line 153 "test_spec_scan.l" +#line 150 "test_spec_scan.l" { /* whitespace */ } YY_BREAK - case 23: + } + + case 22: + { YY_RULE_SETUP -#line 155 "test_spec_scan.l" +#line 152 "test_spec_scan.l" { return T_MONITOR; } YY_BREAK - case 24: + } + + case 23: + { YY_RULE_SETUP -#line 156 "test_spec_scan.l" +#line 153 "test_spec_scan.l" { return T_IMAGE_TARGET; } YY_BREAK - case 25: + } + + case 24: + { YY_RULE_SETUP -#line 157 "test_spec_scan.l" +#line 154 "test_spec_scan.l" { return T_IMAGE; } YY_BREAK - case 26: + } + + case 25: + { YY_RULE_SETUP -#line 158 "test_spec_scan.l" +#line 155 "test_spec_scan.l" { return T_SSL; } YY_BREAK - case 27: + } + + case 26: + { YY_RULE_SETUP -#line 159 "test_spec_scan.l" +#line 156 "test_spec_scan.l" { return T_AUTH_METHOD; } YY_BREAK - case 28: + } + + case 27: + { YY_RULE_SETUP -#line 160 "test_spec_scan.l" +#line 157 "test_spec_scan.l" { return T_AUTH; } YY_BREAK - case 29: + } + + case 28: + { YY_RULE_SETUP -#line 161 "test_spec_scan.l" +#line 158 "test_spec_scan.l" { return T_FORMATION; } YY_BREAK - case 30: + } + + case 29: + { YY_RULE_SETUP -#line 162 "test_spec_scan.l" +#line 159 "test_spec_scan.l" { return T_NUM_SYNC; } YY_BREAK - case 31: + } + + case 30: + { YY_RULE_SETUP -#line 163 "test_spec_scan.l" +#line 160 "test_spec_scan.l" { return T_NODE; } YY_BREAK - case 32: + } + + case 31: + { YY_RULE_SETUP -#line 165 "test_spec_scan.l" +#line 162 "test_spec_scan.l" { return T_COORDINATOR; } YY_BREAK - case 33: + } + + case 32: + { YY_RULE_SETUP -#line 166 "test_spec_scan.l" +#line 163 "test_spec_scan.l" { return T_WORKER; } YY_BREAK - case 34: + } + + case 33: + { YY_RULE_SETUP -#line 167 "test_spec_scan.l" +#line 164 "test_spec_scan.l" { return T_ASYNC; } YY_BREAK - case 35: + } + + case 34: + { YY_RULE_SETUP -#line 168 "test_spec_scan.l" +#line 165 "test_spec_scan.l" { return T_NO_MONITOR; } YY_BREAK - case 36: + } + + case 35: + { YY_RULE_SETUP -#line 169 "test_spec_scan.l" +#line 166 "test_spec_scan.l" { return T_PASSWORD; } YY_BREAK - case 37: + } + + case 36: + { YY_RULE_SETUP -#line 170 "test_spec_scan.l" +#line 167 "test_spec_scan.l" { return T_MONITOR_PASSWORD; } YY_BREAK - case 38: + } + + case 37: + { YY_RULE_SETUP -#line 171 "test_spec_scan.l" +#line 168 "test_spec_scan.l" { return T_LAUNCH; } YY_BREAK - case 39: + } + + case 38: + { YY_RULE_SETUP -#line 172 "test_spec_scan.l" +#line 169 "test_spec_scan.l" { return T_DEFERRED; } YY_BREAK - case 40: + } + + case 39: + { YY_RULE_SETUP -#line 173 "test_spec_scan.l" +#line 170 "test_spec_scan.l" { return T_IMMEDIATE; } YY_BREAK - case 41: + } + + case 40: + { YY_RULE_SETUP -#line 174 "test_spec_scan.l" +#line 171 "test_spec_scan.l" { return T_INITIALLY; } YY_BREAK - case 42: + } + + case 41: + { YY_RULE_SETUP -#line 175 "test_spec_scan.l" +#line 172 "test_spec_scan.l" { return T_STOPPED; } YY_BREAK - case 43: + } + + case 42: + { YY_RULE_SETUP -#line 176 "test_spec_scan.l" +#line 173 "test_spec_scan.l" { return T_VOLUME; } YY_BREAK - case 44: + } + + case 43: + { YY_RULE_SETUP -#line 177 "test_spec_scan.l" +#line 174 "test_spec_scan.l" { return T_LISTEN; } YY_BREAK - case 45: + } + + case 44: + { YY_RULE_SETUP -#line 178 "test_spec_scan.l" +#line 175 "test_spec_scan.l" { return T_CITUS_SECONDARY; } YY_BREAK - case 46: + } + + case 45: + { YY_RULE_SETUP -#line 179 "test_spec_scan.l" +#line 176 "test_spec_scan.l" { return T_CANDIDATE_PRIORITY; } YY_BREAK - case 47: + } + + case 46: + { YY_RULE_SETUP -#line 180 "test_spec_scan.l" +#line 177 "test_spec_scan.l" { return T_GROUP; } YY_BREAK - case 48: + } + + case 47: + { YY_RULE_SETUP -#line 181 "test_spec_scan.l" +#line 178 "test_spec_scan.l" { return T_PORT; } YY_BREAK - case 49: + } + + case 48: + { YY_RULE_SETUP -#line 182 "test_spec_scan.l" +#line 179 "test_spec_scan.l" { return T_CITUS_CLUSTER_NAME; } YY_BREAK - case 50: + } + + case 49: + { YY_RULE_SETUP -#line 183 "test_spec_scan.l" +#line 180 "test_spec_scan.l" { return T_DEBIAN_CLUSTER; } YY_BREAK - case 51: + } + + case 50: + { YY_RULE_SETUP -#line 184 "test_spec_scan.l" +#line 181 "test_spec_scan.l" { return T_REPLICATION_QUORUM; } YY_BREAK - case 52: + } + + case 51: + { YY_RULE_SETUP -#line 185 "test_spec_scan.l" +#line 182 "test_spec_scan.l" { return T_REPLICATION_PASSWORD; } YY_BREAK - case 53: + } + + case 52: + { YY_RULE_SETUP -#line 186 "test_spec_scan.l" +#line 183 "test_spec_scan.l" { return T_EXTENSION_VERSION; } YY_BREAK - case 54: + } + + case 53: + { YY_RULE_SETUP -#line 187 "test_spec_scan.l" +#line 184 "test_spec_scan.l" { return T_BIND_SOURCE; } YY_BREAK - case 55: + } + + case 54: + { YY_RULE_SETUP -#line 189 "test_spec_scan.l" +#line 186 "test_spec_scan.l" { return T_EQUALS; } YY_BREAK - case 56: + } + + case 55: + { YY_RULE_SETUP -#line 191 "test_spec_scan.l" +#line 188 "test_spec_scan.l" { - yylval.ival = atoi(yytext); + yylval.ival = atoi(yytext); /* IGNORE-BANNED */ return T_INTEGER; } YY_BREAK - case 57: + } -/* rule 57 can match eol */ + case 56: + { +/* rule 56 can match eol */ YY_RULE_SETUP -#line 196 "test_spec_scan.l" +#line 193 "test_spec_scan.l" { yytext[yyleng - 1] = '\0'; yylval.str = pgaf_strdup(yytext + 1); @@ -2007,18 +2142,24 @@ YY_DECL } YY_BREAK - case 58: + } + + case 57: + { YY_RULE_SETUP -#line 202 "test_spec_scan.l" +#line 199 "test_spec_scan.l" { pgaf_cluster_depth++; return T_LBRACE; } YY_BREAK - case 59: + } + + case 58: + { YY_RULE_SETUP -#line 207 "test_spec_scan.l" +#line 204 "test_spec_scan.l" { pgaf_cluster_depth--; if (pgaf_cluster_depth == 0) @@ -2029,697 +2170,887 @@ YY_DECL } YY_BREAK - case 60: + } + + case 59: + { YY_RULE_SETUP -#line 214 "test_spec_scan.l" +#line 211 "test_spec_scan.l" { return T_FS_INIT; } YY_BREAK - case 61: + } + + case 60: + { YY_RULE_SETUP -#line 215 "test_spec_scan.l" +#line 212 "test_spec_scan.l" { return T_FS_SINGLE; } YY_BREAK - case 62: + } + + case 61: + { YY_RULE_SETUP -#line 216 "test_spec_scan.l" +#line 213 "test_spec_scan.l" { return T_FS_PRIMARY; } YY_BREAK + } + + case 62: + { + YY_RULE_SETUP +#line 214 "test_spec_scan.l" + { + return T_FS_WAIT_PRIMARY; + } + + YY_BREAK + } + case 63: + { YY_RULE_SETUP -#line 217 "test_spec_scan.l" +#line 215 "test_spec_scan.l" { return T_FS_WAIT_PRIMARY; } YY_BREAK + } + case 64: + { YY_RULE_SETUP -#line 218 "test_spec_scan.l" +#line 216 "test_spec_scan.l" { - return T_FS_WAIT_PRIMARY; + return T_FS_WAIT_STANDBY; } YY_BREAK + } + case 65: + { YY_RULE_SETUP -#line 219 "test_spec_scan.l" +#line 217 "test_spec_scan.l" { return T_FS_WAIT_STANDBY; } YY_BREAK + } + case 66: + { YY_RULE_SETUP -#line 220 "test_spec_scan.l" +#line 218 "test_spec_scan.l" { - return T_FS_WAIT_STANDBY; + return T_FS_DEMOTED; } YY_BREAK + } + case 67: + { YY_RULE_SETUP -#line 221 "test_spec_scan.l" +#line 219 "test_spec_scan.l" { - return T_FS_DEMOTED; + return T_FS_DEMOTE_TIMEOUT; } YY_BREAK + } + case 68: + { YY_RULE_SETUP -#line 222 "test_spec_scan.l" +#line 220 "test_spec_scan.l" { return T_FS_DEMOTE_TIMEOUT; } YY_BREAK + } + case 69: + { YY_RULE_SETUP -#line 223 "test_spec_scan.l" +#line 221 "test_spec_scan.l" { - return T_FS_DEMOTE_TIMEOUT; + return T_FS_DRAINING; } YY_BREAK + } + case 70: + { YY_RULE_SETUP -#line 224 "test_spec_scan.l" +#line 222 "test_spec_scan.l" { - return T_FS_DRAINING; + return T_FS_SECONDARY; } YY_BREAK + } + case 71: + { YY_RULE_SETUP -#line 225 "test_spec_scan.l" +#line 223 "test_spec_scan.l" { - return T_FS_SECONDARY; + return T_FS_CATCHINGUP; } YY_BREAK + } + case 72: + { YY_RULE_SETUP -#line 226 "test_spec_scan.l" +#line 224 "test_spec_scan.l" { - return T_FS_CATCHINGUP; + return T_FS_PREP_PROMOTION; } YY_BREAK + } + case 73: + { YY_RULE_SETUP -#line 227 "test_spec_scan.l" +#line 225 "test_spec_scan.l" { return T_FS_PREP_PROMOTION; } YY_BREAK + } + case 74: + { YY_RULE_SETUP -#line 228 "test_spec_scan.l" +#line 226 "test_spec_scan.l" { - return T_FS_PREP_PROMOTION; + return T_FS_STOP_REPLICATION; } YY_BREAK + } + case 75: + { YY_RULE_SETUP -#line 229 "test_spec_scan.l" +#line 227 "test_spec_scan.l" { return T_FS_STOP_REPLICATION; } YY_BREAK + } + case 76: + { YY_RULE_SETUP -#line 230 "test_spec_scan.l" +#line 228 "test_spec_scan.l" { - return T_FS_STOP_REPLICATION; + return T_FS_MAINTENANCE; } YY_BREAK + } + case 77: + { YY_RULE_SETUP -#line 231 "test_spec_scan.l" +#line 229 "test_spec_scan.l" { - return T_FS_MAINTENANCE; + return T_FS_JOIN_PRIMARY; } YY_BREAK + } + case 78: + { YY_RULE_SETUP -#line 232 "test_spec_scan.l" +#line 230 "test_spec_scan.l" { return T_FS_JOIN_PRIMARY; } YY_BREAK + } + case 79: + { YY_RULE_SETUP -#line 233 "test_spec_scan.l" +#line 231 "test_spec_scan.l" { - return T_FS_JOIN_PRIMARY; + return T_FS_APPLY_SETTINGS; } YY_BREAK + } + case 80: + { YY_RULE_SETUP -#line 234 "test_spec_scan.l" +#line 232 "test_spec_scan.l" { return T_FS_APPLY_SETTINGS; } YY_BREAK + } + case 81: + { YY_RULE_SETUP -#line 235 "test_spec_scan.l" +#line 233 "test_spec_scan.l" { - return T_FS_APPLY_SETTINGS; + return T_FS_PREPARE_MAINTENANCE; } YY_BREAK + } + case 82: + { YY_RULE_SETUP -#line 236 "test_spec_scan.l" +#line 234 "test_spec_scan.l" { return T_FS_PREPARE_MAINTENANCE; } YY_BREAK + } + case 83: + { YY_RULE_SETUP -#line 237 "test_spec_scan.l" +#line 235 "test_spec_scan.l" { - return T_FS_PREPARE_MAINTENANCE; + return T_FS_WAIT_MAINTENANCE; } YY_BREAK + } + case 84: + { YY_RULE_SETUP -#line 238 "test_spec_scan.l" +#line 236 "test_spec_scan.l" { return T_FS_WAIT_MAINTENANCE; } YY_BREAK + } + case 85: + { YY_RULE_SETUP -#line 239 "test_spec_scan.l" +#line 237 "test_spec_scan.l" { - return T_FS_WAIT_MAINTENANCE; + return T_FS_REPORT_LSN; } YY_BREAK + } + case 86: + { YY_RULE_SETUP -#line 240 "test_spec_scan.l" +#line 238 "test_spec_scan.l" { return T_FS_REPORT_LSN; } YY_BREAK + } + case 87: + { YY_RULE_SETUP -#line 241 "test_spec_scan.l" +#line 239 "test_spec_scan.l" { - return T_FS_REPORT_LSN; + return T_FS_FAST_FORWARD; } YY_BREAK + } + case 88: + { YY_RULE_SETUP -#line 242 "test_spec_scan.l" +#line 240 "test_spec_scan.l" { return T_FS_FAST_FORWARD; } YY_BREAK + } + case 89: + { YY_RULE_SETUP -#line 243 "test_spec_scan.l" +#line 241 "test_spec_scan.l" { - return T_FS_FAST_FORWARD; + return T_FS_JOIN_SECONDARY; } YY_BREAK + } + case 90: + { YY_RULE_SETUP -#line 244 "test_spec_scan.l" +#line 242 "test_spec_scan.l" { return T_FS_JOIN_SECONDARY; } YY_BREAK - case 91: - YY_RULE_SETUP -#line 245 "test_spec_scan.l" - { - return T_FS_JOIN_SECONDARY; - } + } - YY_BREAK - case 92: + case 91: + { YY_RULE_SETUP -#line 246 "test_spec_scan.l" +#line 243 "test_spec_scan.l" { return T_FS_DROPPED; } YY_BREAK - case 93: + } + + case 92: + { YY_RULE_SETUP -#line 248 "test_spec_scan.l" +#line 245 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); return T_IDENT; } YY_BREAK - case 94: + } + + case 93: + { YY_RULE_SETUP -#line 253 "test_spec_scan.l" +#line 250 "test_spec_scan.l" { /* comment */ } YY_BREAK - case 95: + } -/* rule 95 can match eol */ + case 94: + { +/* rule 94 can match eol */ YY_RULE_SETUP -#line 254 "test_spec_scan.l" +#line 251 "test_spec_scan.l" { pgaf_line_number++; } YY_BREAK - case 96: + } + + case 95: + { YY_RULE_SETUP -#line 255 "test_spec_scan.l" +#line 252 "test_spec_scan.l" { /* whitespace */ } YY_BREAK - case 97: + } + + case 96: + { YY_RULE_SETUP -#line 257 "test_spec_scan.l" +#line 254 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_EXEC_FAILS; } YY_BREAK - case 98: + } + + case 97: + { YY_RULE_SETUP -#line 258 "test_spec_scan.l" +#line 255 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_EXEC; } YY_BREAK - case 99: + } + + case 98: + { YY_RULE_SETUP -#line 259 "test_spec_scan.l" +#line 256 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_PG_AUTOCTL; } YY_BREAK - case 100: + } + + case 99: + { YY_RULE_SETUP -#line 261 "test_spec_scan.l" +#line 258 "test_spec_scan.l" { return T_WAIT; } YY_BREAK - case 101: + } + + case 100: + { YY_RULE_SETUP -#line 262 "test_spec_scan.l" +#line 259 "test_spec_scan.l" { return T_UNTIL; } YY_BREAK - case 102: + } + + case 101: + { YY_RULE_SETUP -#line 263 "test_spec_scan.l" +#line 260 "test_spec_scan.l" { return T_TIMEOUT; } YY_BREAK - case 103: + } + + case 102: + { YY_RULE_SETUP -#line 264 "test_spec_scan.l" +#line 261 "test_spec_scan.l" { return T_ASSERT; } YY_BREAK - case 104: + } + + case 103: + { YY_RULE_SETUP -#line 265 "test_spec_scan.l" +#line 262 "test_spec_scan.l" { return T_SQL; } YY_BREAK - case 105: + } + + case 104: + { YY_RULE_SETUP -#line 266 "test_spec_scan.l" +#line 263 "test_spec_scan.l" { return T_EXPECT; } YY_BREAK - case 106: + } + + case 105: + { YY_RULE_SETUP -#line 267 "test_spec_scan.l" +#line 264 "test_spec_scan.l" { return T_ERROR; } YY_BREAK - case 107: + } + + case 106: + { YY_RULE_SETUP -#line 268 "test_spec_scan.l" +#line 265 "test_spec_scan.l" { return T_PROMOTE; } YY_BREAK - case 108: + } + + case 107: + { YY_RULE_SETUP -#line 269 "test_spec_scan.l" +#line 266 "test_spec_scan.l" { return T_NETWORK; } YY_BREAK - case 109: + } + + case 108: + { YY_RULE_SETUP -#line 270 "test_spec_scan.l" +#line 267 "test_spec_scan.l" { return T_DISCONNECT; } YY_BREAK - case 110: + } + + case 109: + { YY_RULE_SETUP -#line 271 "test_spec_scan.l" +#line 268 "test_spec_scan.l" { return T_CONNECT; } YY_BREAK - case 111: + } + + case 110: + { YY_RULE_SETUP -#line 272 "test_spec_scan.l" +#line 269 "test_spec_scan.l" { return T_SLEEP; } YY_BREAK - case 112: + } + + case 111: + { YY_RULE_SETUP -#line 273 "test_spec_scan.l" +#line 270 "test_spec_scan.l" { return T_COMPOSE; } YY_BREAK - case 113: + } + + case 112: + { YY_RULE_SETUP -#line 274 "test_spec_scan.l" +#line 271 "test_spec_scan.l" { return T_DOWN; } YY_BREAK - case 114: + } + + case 113: + { YY_RULE_SETUP -#line 275 "test_spec_scan.l" +#line 272 "test_spec_scan.l" { return T_START; } YY_BREAK - case 115: + } + + case 114: + { YY_RULE_SETUP -#line 276 "test_spec_scan.l" +#line 273 "test_spec_scan.l" { return T_STOP; } YY_BREAK - case 116: + } + + case 115: + { YY_RULE_SETUP -#line 277 "test_spec_scan.l" +#line 274 "test_spec_scan.l" { return T_STOPPED; } YY_BREAK - case 117: + } + + case 116: + { YY_RULE_SETUP -#line 278 "test_spec_scan.l" +#line 275 "test_spec_scan.l" { return T_KILL; } YY_BREAK - case 118: + } + + case 117: + { YY_RULE_SETUP -#line 279 "test_spec_scan.l" +#line 276 "test_spec_scan.l" { return T_IN; } YY_BREAK - case 119: + } + + case 118: + { YY_RULE_SETUP -#line 280 "test_spec_scan.l" +#line 277 "test_spec_scan.l" { return T_STATE; } YY_BREAK - case 120: + } + + case 119: + { YY_RULE_SETUP -#line 281 "test_spec_scan.l" +#line 278 "test_spec_scan.l" { return T_ASSIGNED_STATE; } YY_BREAK - case 121: + } + + case 120: + { YY_RULE_SETUP -#line 282 "test_spec_scan.l" +#line 279 "test_spec_scan.l" { return T_CANDIDATE_PRIORITY; } YY_BREAK - case 122: + } + + case 121: + { YY_RULE_SETUP -#line 283 "test_spec_scan.l" +#line 280 "test_spec_scan.l" { return T_GROUP; } YY_BREAK - case 123: + } + + case 122: + { YY_RULE_SETUP -#line 284 "test_spec_scan.l" +#line 281 "test_spec_scan.l" { return T_AND; } YY_BREAK - case 124: + } + + case 123: + { YY_RULE_SETUP -#line 285 "test_spec_scan.l" +#line 282 "test_spec_scan.l" { return T_IS; } YY_BREAK - case 125: + } + + case 124: + { YY_RULE_SETUP -#line 286 "test_spec_scan.l" +#line 283 "test_spec_scan.l" { return T_WITH; } YY_BREAK - case 126: + } + + case 125: + { YY_RULE_SETUP -#line 287 "test_spec_scan.l" +#line 284 "test_spec_scan.l" { return T_EQUALS; } YY_BREAK - case 127: + } + + case 126: + { YY_RULE_SETUP -#line 288 "test_spec_scan.l" +#line 285 "test_spec_scan.l" { return T_COMMA; } YY_BREAK - case 128: + } + + case 127: + { YY_RULE_SETUP -#line 289 "test_spec_scan.l" +#line 286 "test_spec_scan.l" { return T_POSTGRES; } YY_BREAK - case 129: + } + + case 128: + { YY_RULE_SETUP -#line 290 "test_spec_scan.l" +#line 287 "test_spec_scan.l" { return T_STAYS; } YY_BREAK - case 130: + } + + case 129: + { YY_RULE_SETUP -#line 291 "test_spec_scan.l" +#line 288 "test_spec_scan.l" { return T_WHILE; } YY_BREAK - case 131: + } + + case 130: + { YY_RULE_SETUP -#line 292 "test_spec_scan.l" +#line 289 "test_spec_scan.l" { return T_THROUGH; } YY_BREAK - case 132: + } + + case 131: + { YY_RULE_SETUP -#line 293 "test_spec_scan.l" +#line 290 "test_spec_scan.l" { return T_SET; } YY_BREAK - case 133: + } + + case 132: + { YY_RULE_SETUP -#line 294 "test_spec_scan.l" +#line 291 "test_spec_scan.l" { BEGIN(EXEC_ARGS); return T_INJECT; } YY_BREAK - case 134: - YY_RULE_SETUP -#line 295 "test_spec_scan.l" - { - return T_LOGS; - } - - YY_BREAK - case 135: - YY_RULE_SETUP -#line 296 "test_spec_scan.l" - { - return T_NOT; - } + } - YY_BREAK - case 136: + case 133: + { YY_RULE_SETUP -#line 297 "test_spec_scan.l" +#line 292 "test_spec_scan.l" { - return T_CONTAINS; + return T_LOGS; } YY_BREAK - case 137: - YY_RULE_SETUP -#line 298 "test_spec_scan.l" - { - return T_MATCHES; - } + } - YY_BREAK - case 138: + case 134: + { YY_RULE_SETUP -#line 299 "test_spec_scan.l" +#line 293 "test_spec_scan.l" { - return T_NODE_ACTIVE; + return T_NOT; } YY_BREAK - case 139: - YY_RULE_SETUP -#line 300 "test_spec_scan.l" - { - return T_MARK; - } + } - YY_BREAK - case 140: + case 135: + { YY_RULE_SETUP -#line 301 "test_spec_scan.l" +#line 294 "test_spec_scan.l" { - return T_HEALTHY; + return T_CONTAINS; } YY_BREAK - case 141: - YY_RULE_SETUP -#line 302 "test_spec_scan.l" - { - return T_UNHEALTHY; - } + } - YY_BREAK - case 142: + case 136: + { YY_RULE_SETUP -#line 303 "test_spec_scan.l" +#line 295 "test_spec_scan.l" { - return T_STATES; + return T_MATCHES; } YY_BREAK - case 143: - YY_RULE_SETUP -#line 304 "test_spec_scan.l" - { - return ':'; - } + } - YY_BREAK - case 144: + case 137: + { YY_RULE_SETUP -#line 306 "test_spec_scan.l" +#line 297 "test_spec_scan.l" { - yylval.ival = atoi(yytext); + yylval.ival = atoi(yytext); /* IGNORE-BANNED */ return T_INTEGER; } YY_BREAK - case 145: + } -/* rule 145 can match eol */ + case 138: + { +/* rule 138 can match eol */ YY_RULE_SETUP -#line 311 "test_spec_scan.l" +#line 302 "test_spec_scan.l" { yytext[yyleng - 1] = '\0'; yylval.str = pgaf_strdup(yytext + 1); @@ -2727,9 +3058,12 @@ YY_DECL } YY_BREAK - case 146: + } + + case 139: + { YY_RULE_SETUP -#line 317 "test_spec_scan.l" +#line 308 "test_spec_scan.l" { if (pgaf_next_brace_is_while) { @@ -2742,9 +3076,12 @@ YY_DECL } YY_BREAK - case 147: + } + + case 140: + { YY_RULE_SETUP -#line 327 "test_spec_scan.l" +#line 318 "test_spec_scan.l" { if (pgaf_step_brace_depth > 0) { @@ -2757,25 +3094,34 @@ YY_DECL } YY_BREAK - case 148: + } + + case 141: + { YY_RULE_SETUP -#line 337 "test_spec_scan.l" +#line 328 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); return T_IDENT; } YY_BREAK - case 149: + } + + case 142: + { YY_RULE_SETUP -#line 342 "test_spec_scan.l" +#line 333 "test_spec_scan.l" { /* skip whitespace before service name */ } YY_BREAK - case 150: + } + + case 143: + { YY_RULE_SETUP -#line 344 "test_spec_scan.l" +#line 335 "test_spec_scan.l" { yylval.str = pgaf_strdup(yytext); BEGIN(EXEC_ARGS_REST); @@ -2783,20 +3129,25 @@ YY_DECL } YY_BREAK - case 151: + } -/* rule 151 can match eol */ + case 144: + { +/* rule 144 can match eol */ YY_RULE_SETUP -#line 350 "test_spec_scan.l" +#line 341 "test_spec_scan.l" { pgaf_line_number++; BEGIN(STEP_BODY); } YY_BREAK - case 152: + } + + case 145: + { YY_RULE_SETUP -#line 355 "test_spec_scan.l" +#line 346 "test_spec_scan.l" { char *p = yytext; while (*p == ' ' || *p == '\t') @@ -2809,30 +3160,39 @@ YY_DECL } YY_BREAK - case 153: + } -/* rule 153 can match eol */ + case 146: + { +/* rule 146 can match eol */ YY_RULE_SETUP -#line 363 "test_spec_scan.l" +#line 354 "test_spec_scan.l" { pgaf_line_number++; BEGIN(STEP_BODY); } YY_BREAK - case 154: + } + + case 147: + { YY_RULE_SETUP -#line 368 "test_spec_scan.l" +#line 359 "test_spec_scan.l" ECHO; YY_BREAK -#line 2357 "test_spec_scan.c" + } + +#line 2301 "test_spec_scan.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CLUSTER_BODY): case YY_STATE_EOF(STEP_BODY): case YY_STATE_EOF(EXEC_ARGS): case YY_STATE_EOF(EXEC_ARGS_REST): + { yyterminate(); + } case YY_END_OF_BUFFER: { @@ -2866,8 +3226,8 @@ YY_DECL * end-of-buffer state). Contrast this with the test * in input(). */ - if ((yy_c_buf_p) <= - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]) + if ((yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] + ) { /* This was really a NUL. */ yy_state_type yy_next_state; @@ -2937,6 +3297,7 @@ YY_DECL } case EOB_ACT_CONTINUE_SCAN: + { (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; @@ -2945,8 +3306,10 @@ YY_DECL yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; + } case EOB_ACT_LAST_MATCH: + { (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; @@ -2955,14 +3318,17 @@ YY_DECL yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; + } } } break; } default: + { YY_FATAL_ERROR( "fatal flex scanner internal error--no action found"); + } } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ @@ -3151,7 +3517,7 @@ yy_get_previous_state(void) while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { yy_current_state = (int) yy_def[yy_current_state]; - if (yy_current_state >= 1196) + if (yy_current_state >= 1162) { yy_c = yy_meta[yy_c]; } @@ -3183,13 +3549,13 @@ yy_try_NUL_trans(yy_state_type yy_current_state) while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { yy_current_state = (int) yy_def[yy_current_state]; - if (yy_current_state >= 1196) + if (yy_current_state >= 1162) { yy_c = yy_meta[yy_c]; } } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 1195); + yy_is_jam = (yy_current_state == 1161); return yy_is_jam ? 0 : yy_current_state; } @@ -3231,7 +3597,7 @@ input(void) switch (yy_get_next_buffer()) { case EOB_ACT_LAST_MATCH: - + { /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to @@ -3244,6 +3610,7 @@ input(void) /* Reset buffer status. */ yyrestart(yyin); + } /*FALLTHROUGH*/ @@ -3266,8 +3633,10 @@ input(void) } case EOB_ACT_CONTINUE_SCAN: + { (yy_c_buf_p) = (yytext_ptr) + offset; break; + } } } } @@ -3702,7 +4071,7 @@ yy_scan_bytes(const char *yybytes, yy_size_t _yybytes_len) static void yynoreturn yy_fatal_error(const char *msg) { - fprintf(stderr, "%s\n", msg); + fprintf(stderr, "%s\n", msg); /* IGNORE-BANNED */ exit(YY_EXIT_FAILURE); } @@ -3937,7 +4306,7 @@ yyfree(void *ptr) #define YYTABLES_NAME "yytables" -#line 368 "test_spec_scan.l" +#line 359 "test_spec_scan.l" static void diff --git a/src/bin/pgaftest/test_spec_scan.l b/src/bin/pgaftest/test_spec_scan.l index 4a1352131..0ee5846d2 100644 --- a/src/bin/pgaftest/test_spec_scan.l +++ b/src/bin/pgaftest/test_spec_scan.l @@ -31,10 +31,8 @@ int pgaf_line_number = 1; static int pgaf_next_brace_is_step = 0; /* - * When the lexer sees "cluster" or "scenario", it sets this flag so the - * next "{" enters CLUSTER_BODY rather than doing the raw block read. - * The CLUSTER_BODY state is reused for "scenario" since the inner syntax - * (formation, node names, ssl, auth) is identical. + * When the lexer sees "cluster", it sets this flag so the next "{" + * enters CLUSTER_BODY rather than doing the raw block read. */ static int pgaf_next_brace_is_cluster = 0; @@ -93,7 +91,6 @@ static void pgaf_read_raw_block(void); "#"[^\n]* { /* comment */ } "cluster" { pgaf_next_brace_is_cluster = 1; return T_CLUSTER; } -"scenario" { pgaf_next_brace_is_cluster = 1; return T_SCENARIO; } "monitor" { return T_MONITOR; } "node" { return T_NODE; } "citus-coordinator" { return T_CITUS_COORDINATOR; } @@ -296,12 +293,6 @@ static void pgaf_read_raw_block(void); "not" { return T_NOT; } "contains" { return T_CONTAINS; } "matches" { return T_MATCHES; } -"node_active" { return T_NODE_ACTIVE; } -"mark" { return T_MARK; } -"healthy" { return T_HEALTHY; } -"unhealthy" { return T_UNHEALTHY; } -"states" { return T_STATES; } -":" { return ':'; } [0-9]+[sS]? { yylval.ival = atoi(yytext); diff --git a/src/monitor/Makefile b/src/monitor/Makefile index f5f826d19..5da72634a 100644 --- a/src/monitor/Makefile +++ b/src/monitor/Makefile @@ -14,7 +14,7 @@ MODULE_big = $(EXTENSION) OBJS = $(patsubst ${SRC_DIR}%.c,%.o,$(wildcard ${SRC_DIR}*.c)) PG_CPPFLAGS = -std=c99 -Wall -Werror -Wno-unused-parameter -Iinclude -I$(libpq_srcdir) -g SHLIB_LINK = $(libpq) -REGRESS = create_extension monitor workers dummy_update drop_extension upgrade +REGRESS = create_extension monitor workers dummy_update node_active_protocol drop_extension upgrade PG_CONFIG ?= pg_config PGXS = $(shell $(PG_CONFIG) --pgxs) diff --git a/src/monitor/expected/node_active_protocol.out b/src/monitor/expected/node_active_protocol.out new file mode 100644 index 000000000..77d9cff8c --- /dev/null +++ b/src/monitor/expected/node_active_protocol.out @@ -0,0 +1,420 @@ +-- Copyright (c) Microsoft Corporation. All rights reserved. +-- Licensed under the PostgreSQL License. +-- +-- Regression tests for the monitor's node_active() protocol. +-- +-- Covers two concrete regressions: +-- +-- #1062 — Primary has health=BAD (health-check worker cannot reach it) but +-- IS calling node_active with pgIsRunning=true. NodeIsHealthy must +-- return true via the fresh-report override so no spurious failover +-- is triggered. +-- +-- #1032 — After a failover the old primary catches up while the health +-- checker still marks it BAD. The fixed NodeIsHealthy() allows +-- catchingup→secondary to proceed. Without the fix the transition +-- was permanently blocked (NodeIsHealthy returned false for any +-- node with health=BAD regardless of the live report). +-- +-- Additional regression: NODE_HEALTH_UNKNOWN (-1) is the initial DB value for +-- newly registered nodes (no health-check worker has run yet). NodeIsHealthy +-- must treat UNKNOWN as "trust the keeper's own pgIsRunning report." This +-- manifests during formation bootstrap: the catchingup→secondary transition +-- requires NodeIsHealthy(joining-node) to be true. +-- +-- Also exercises the stale in-memory struct fix in NodeActive(): after +-- ReportAutoFailoverNodeState writes pgIsRunning to the DB, the same value +-- must be synced back into the pgAutoFailoverNode struct before +-- ProceedGroupState runs, otherwise pgIsRunning appears stale to +-- NodeIsHealthy when the keeper changes from pgIsRunning=false to true. +\x on +-- ── formation and node registration ───────────────────────────────────────── +SELECT pgautofailover.create_formation('fsm_test', 'pgsql', 'postgres', true); +-[ RECORD 1 ]--------+--------- +formationid | fsm_test +kind | pgsql +dbname | postgres +opt_secondary | t +number_sync_standbys | 1 + +-- sysidentifier=1: a non-zero value satisfies the same_system_identifier +-- constraint without a separate set_node_system_identifier() call. +SELECT * + FROM pgautofailover.register_node('fsm_test', 'node1', 5432, + 'postgres', 'node1', 1); +-[ RECORD 1 ]---------------+------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | single +assigned_candidate_priority | 100 +assigned_replication_quorum | t +assigned_node_name | node1 + +SELECT * + FROM pgautofailover.register_node('fsm_test', 'node2', 5432, + 'postgres', 'node2', 1); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | wait_standby +assigned_candidate_priority | 100 +assigned_replication_quorum | t +assigned_node_name | node2 + +-- ── formation bootstrap ────────────────────────────────────────────────────── +-- +-- IsCurrentState(node, S) requires both goalState=S and reportedState=S, so +-- every intermediate state must be explicitly confirmed before the next guard +-- fires. The sequence below mirrors what two real keepers would produce. +-- node1: single (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'single'); +-[ RECORD 1 ]---------------+------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | single +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2: wait_standby (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_standby'); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | wait_standby +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node1: single → wait_primary (secondary has joined in WAIT_STANDBY) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'single', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | wait_primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node1: wait_primary (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'wait_primary', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | wait_primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2: wait_standby → catchingup (primary is confirmed in WAIT_PRIMARY) +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_standby'); +-[ RECORD 1 ]---------------+----------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | catchingup +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2: catchingup → secondary +-- NODE_HEALTH_UNKNOWN (-1) regression: health is -1 (default for new nodes; +-- the health-check worker has not run). NodeIsHealthy must trust the +-- keeper's pgIsRunning=true instead of returning false. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'catchingup', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2: secondary (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node1: wait_primary → primary (secondary quorum satisfied) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'wait_primary', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- ── test_001: steady state ─────────────────────────────────────────────────── +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- ── test_002: issue #1062 ───────────────────────────────────────────────────── +-- +-- Health checker marks primary BAD while the primary is still calling +-- node_active with pgIsRunning=true. NodeIsHealthy must return true via the +-- fresh-report override: +-- health=BAD, healthchecktime < reportTime, reportTime within 1s of now. +-- No spurious failover must be triggered. +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now() - interval '1 second' + WHERE nodename = 'node1'; +UPDATE 1 +-- Primary reports pgIsRunning=true; fresh report overrides the BAD health. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_pg_is_running => true, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- Secondary calls in; NodeIsUnhealthy(primary) is false — no promotion. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- restore health before the full-failure test +UPDATE pgautofailover.node + SET health = 1, + healthchecktime = now() + WHERE nodename = 'node1'; +UPDATE 1 +-- ── test_003: two-node failover ─────────────────────────────────────────────── +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now() - interval '1 second' + WHERE nodename = 'node1'; +UPDATE 1 +-- Primary's own heartbeat with pgIsRunning=false. In the two-node case +-- ProceedGroupStateForPrimaryNode has no self-demotion rule; the failover +-- trigger fires from the standby's heartbeat. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_pg_is_running => false, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- Secondary calls in: NodeIsUnhealthy(primary) is true → prepare_promotion. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+------------------ +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | prepare_promotion +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2 reports prepare_promotion → assigned stop_replication. +-- node1 gets goalState=demote_timeout. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'prepare_promotion', + current_pg_is_running => true, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+----------------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | stop_replication +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node1 reports demote_timeout; satisfies IsCurrentState(node1, DEMOTE_TIMEOUT) +-- so that the next node2 heartbeat can advance. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'demote_timeout', + current_pg_is_running => false, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+--------------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | demote_timeout +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2 reports stop_replication → assigned wait_primary. +-- node1 gets goalState=demoted. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'stop_replication', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | wait_primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2 in wait_primary; no secondary in quorum yet. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_primary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | wait_primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- ── test_004: issue #1032 ───────────────────────────────────────────────────── +-- +-- Old primary (node1) resurfaces. Health checker is still marking it BAD +-- (recovery in progress). The fixed NodeIsHealthy() must allow the +-- catchingup→secondary transition. +-- +-- The stale in-memory struct fix is also exercised here: node1's previous +-- node_active call reported pgIsRunning=false (demoted). The DB therefore +-- has reportedpgisrunning=false. When node1 reports catchingup with +-- pgIsRunning=true, ReportAutoFailoverNodeState writes true to the DB but the +-- in-memory struct still holds false. Without the fix, ProceedGroupState +-- sees pgIsRunning=false and NodeIsHealthy returns false, permanently blocking +-- the transition. +UPDATE pgautofailover.node + SET health = 1, + healthchecktime = now() + WHERE nodename = 'node1'; +UPDATE 1 +-- node1 resurfaces reporting 'primary' while its goalState is 'demoted'. +-- IsCurrentState(node1, DEMOTED) is false (reportedState mismatch), so no +-- DEMOTED rule fires; the monitor returns the current goalState = demoted. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_pg_is_running => true, + current_tli => 1, + current_lsn => '0/4F00'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | demoted +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node1 reports demoted → catchingup assigned. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'demoted', + current_pg_is_running => false, + current_tli => 1, + current_lsn => '0/4F00'); +-[ RECORD 1 ]---------------+----------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | catchingup +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- Health checker marks node1 BAD again (recovery still in progress). +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now() - interval '1 second' + WHERE nodename = 'node1'; +UPDATE 1 +-- node1 calls node_active with pgIsRunning=true. +-- NodeIsHealthy(node1) returns true via the fresh-report override. +-- The stale-struct fix ensures the pgIsRunning=true from this call's report +-- is visible to ProceedGroupState within the same call. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'catchingup', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node1 confirms secondary. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 1 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- node2 now has a healthy secondary in the quorum → promoted to primary. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_primary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 2 +assigned_group_id | 0 +assigned_group_state | primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t diff --git a/src/monitor/sql/node_active_protocol.sql b/src/monitor/sql/node_active_protocol.sql new file mode 100644 index 000000000..e6ce8b587 --- /dev/null +++ b/src/monitor/sql/node_active_protocol.sql @@ -0,0 +1,270 @@ +-- Copyright (c) Microsoft Corporation. All rights reserved. +-- Licensed under the PostgreSQL License. +-- +-- Regression tests for the monitor's node_active() protocol. +-- +-- Covers two concrete regressions: +-- +-- #1062 — Primary has health=BAD (health-check worker cannot reach it) but +-- IS calling node_active with pgIsRunning=true. NodeIsHealthy must +-- return true via the fresh-report override so no spurious failover +-- is triggered. +-- +-- #1032 — After a failover the old primary catches up while the health +-- checker still marks it BAD. The fixed NodeIsHealthy() allows +-- catchingup→secondary to proceed. Without the fix the transition +-- was permanently blocked (NodeIsHealthy returned false for any +-- node with health=BAD regardless of the live report). +-- +-- Additional regression: NODE_HEALTH_UNKNOWN (-1) is the initial DB value for +-- newly registered nodes (no health-check worker has run yet). NodeIsHealthy +-- must treat UNKNOWN as "trust the keeper's own pgIsRunning report." This +-- manifests during formation bootstrap: the catchingup→secondary transition +-- requires NodeIsHealthy(joining-node) to be true. +-- +-- Also exercises the stale in-memory struct fix in NodeActive(): after +-- ReportAutoFailoverNodeState writes pgIsRunning to the DB, the same value +-- must be synced back into the pgAutoFailoverNode struct before +-- ProceedGroupState runs, otherwise pgIsRunning appears stale to +-- NodeIsHealthy when the keeper changes from pgIsRunning=false to true. + +\x on + +-- ── formation and node registration ───────────────────────────────────────── + +SELECT pgautofailover.create_formation('fsm_test', 'pgsql', 'postgres', true); + +-- sysidentifier=1: a non-zero value satisfies the same_system_identifier +-- constraint without a separate set_node_system_identifier() call. +SELECT * + FROM pgautofailover.register_node('fsm_test', 'node1', 5432, + 'postgres', 'node1', 1); + +SELECT * + FROM pgautofailover.register_node('fsm_test', 'node2', 5432, + 'postgres', 'node2', 1); + +-- ── formation bootstrap ────────────────────────────────────────────────────── +-- +-- IsCurrentState(node, S) requires both goalState=S and reportedState=S, so +-- every intermediate state must be explicitly confirmed before the next guard +-- fires. The sequence below mirrors what two real keepers would produce. + +-- node1: single (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'single'); + +-- node2: wait_standby (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_standby'); + +-- node1: single → wait_primary (secondary has joined in WAIT_STANDBY) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'single', + current_lsn => '0/5000'); + +-- node1: wait_primary (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'wait_primary', + current_lsn => '0/5000'); + +-- node2: wait_standby → catchingup (primary is confirmed in WAIT_PRIMARY) +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_standby'); + +-- node2: catchingup → secondary +-- NODE_HEALTH_UNKNOWN (-1) regression: health is -1 (default for new nodes; +-- the health-check worker has not run). NodeIsHealthy must trust the +-- keeper's pgIsRunning=true instead of returning false. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'catchingup', + current_lsn => '0/5000'); + +-- node2: secondary (confirm) +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_lsn => '0/5000'); + +-- node1: wait_primary → primary (secondary quorum satisfied) +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'wait_primary', + current_lsn => '0/5000'); + +-- ── test_001: steady state ─────────────────────────────────────────────────── + +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_lsn => '0/5000'); + +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_lsn => '0/5000'); + +-- ── test_002: issue #1062 ───────────────────────────────────────────────────── +-- +-- Health checker marks primary BAD while the primary is still calling +-- node_active with pgIsRunning=true. NodeIsHealthy must return true via the +-- fresh-report override: +-- health=BAD, healthchecktime < reportTime, reportTime within 1s of now. +-- No spurious failover must be triggered. + +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now() - interval '1 second' + WHERE nodename = 'node1'; + +-- Primary reports pgIsRunning=true; fresh report overrides the BAD health. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_pg_is_running => true, + current_lsn => '0/5000'); + +-- Secondary calls in; NodeIsUnhealthy(primary) is false — no promotion. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_lsn => '0/5000'); + +-- restore health before the full-failure test +UPDATE pgautofailover.node + SET health = 1, + healthchecktime = now() + WHERE nodename = 'node1'; + +-- ── test_003: two-node failover ─────────────────────────────────────────────── + +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now() - interval '1 second' + WHERE nodename = 'node1'; + +-- Primary's own heartbeat with pgIsRunning=false. In the two-node case +-- ProceedGroupStateForPrimaryNode has no self-demotion rule; the failover +-- trigger fires from the standby's heartbeat. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_pg_is_running => false, + current_lsn => '0/5000'); + +-- Secondary calls in: NodeIsUnhealthy(primary) is true → prepare_promotion. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_lsn => '0/5000'); + +-- node2 reports prepare_promotion → assigned stop_replication. +-- node1 gets goalState=demote_timeout. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'prepare_promotion', + current_pg_is_running => true, + current_lsn => '0/5000'); + +-- node1 reports demote_timeout; satisfies IsCurrentState(node1, DEMOTE_TIMEOUT) +-- so that the next node2 heartbeat can advance. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'demote_timeout', + current_pg_is_running => false, + current_lsn => '0/5000'); + +-- node2 reports stop_replication → assigned wait_primary. +-- node1 gets goalState=demoted. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'stop_replication', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); + +-- node2 in wait_primary; no secondary in quorum yet. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_primary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); + +-- ── test_004: issue #1032 ───────────────────────────────────────────────────── +-- +-- Old primary (node1) resurfaces. Health checker is still marking it BAD +-- (recovery in progress). The fixed NodeIsHealthy() must allow the +-- catchingup→secondary transition. +-- +-- The stale in-memory struct fix is also exercised here: node1's previous +-- node_active call reported pgIsRunning=false (demoted). The DB therefore +-- has reportedpgisrunning=false. When node1 reports catchingup with +-- pgIsRunning=true, ReportAutoFailoverNodeState writes true to the DB but the +-- in-memory struct still holds false. Without the fix, ProceedGroupState +-- sees pgIsRunning=false and NodeIsHealthy returns false, permanently blocking +-- the transition. + +UPDATE pgautofailover.node + SET health = 1, + healthchecktime = now() + WHERE nodename = 'node1'; + +-- node1 resurfaces reporting 'primary' while its goalState is 'demoted'. +-- IsCurrentState(node1, DEMOTED) is false (reportedState mismatch), so no +-- DEMOTED rule fires; the monitor returns the current goalState = demoted. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'primary', + current_pg_is_running => true, + current_tli => 1, + current_lsn => '0/4F00'); + +-- node1 reports demoted → catchingup assigned. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'demoted', + current_pg_is_running => false, + current_tli => 1, + current_lsn => '0/4F00'); + +-- Health checker marks node1 BAD again (recovery still in progress). +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now() - interval '1 second' + WHERE nodename = 'node1'; + +-- node1 calls node_active with pgIsRunning=true. +-- NodeIsHealthy(node1) returns true via the fresh-report override. +-- The stale-struct fix ensures the pgIsRunning=true from this call's report +-- is visible to ProceedGroupState within the same call. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'catchingup', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); + +-- node1 confirms secondary. +SELECT * + FROM pgautofailover.node_active('fsm_test', 1, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); + +-- node2 now has a healthy secondary in the quorum → promoted to primary. +SELECT * + FROM pgautofailover.node_active('fsm_test', 2, 0, + current_group_role => 'wait_primary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); diff --git a/tests/tap/specs/monitor_fsm_health.pgaf b/tests/tap/specs/monitor_fsm_health.pgaf deleted file mode 100644 index 4c04f1c1b..000000000 --- a/tests/tap/specs/monitor_fsm_health.pgaf +++ /dev/null @@ -1,198 +0,0 @@ -# Monitor FSM health-predicate regression tests. -# -# Covers the behaviour exposed by issues #1062 and #1032. -# -# Background -# ---------- -# The original IsHealthy() function had an inverted condition in its -# "recent-report overrides bad health-check" clause: -# -# TimestampDifferenceExceeds(reportTime, now, 1s) /* now − reportTime > 1 s */ -# -# Because reportTime is set inside the same node_active() call and ctx->now is -# captured microseconds later, now − reportTime is always ~0 ms — the clause -# never fired. The predicate therefore reduced to: -# -# health == GOOD && pgIsRunning -# -# NodeIsHealthy() in this branch uses the corrected form: -# -# !TimestampDifferenceExceeds(reportTime, ctx->now, 1s) /* < 1 s */ -# -# which fires for the current reporter, matching the comment's stated intent. -# -# The fix matters in two concrete scenarios: -# -# #1062 — Primary has health=BAD (health-check worker cannot reach it) but -# IS calling node_active. No spurious failover should fire. -# -# #1032 — After a failover the old primary catches up as a secondary while -# the health checker is still marking it BAD (recovery in progress). -# With the original bug the catchingup→secondary transition was -# permanently blocked. The fix unblocks it. - -scenario { - formation { - node1 - node2 - } -} - -setup { - # Bootstrap the two-node formation from scratch using node_active calls. - # In scenario mode there are no keepers; we drive the monitor FSM directly. - node_active { node1 reported: init lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: single } - node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: single } - node_active { node2 reported: init lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: wait_standby } - node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: wait_standby } - node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: wait_primary } - node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: wait_primary } - node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: catchingup } - node_active { node2 reported: catchingup lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } - node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: primary } -} - -teardown { - compose down -} - -# ───────────────────────────────────────────────────────────────────────────── -# test_001 — stable baseline -# ───────────────────────────────────────────────────────────────────────────── -step test_001_steady_state { - node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: primary } - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } -} - -# ───────────────────────────────────────────────────────────────────────────── -# test_002 — issue #1062 -# -# Health checker marks primary BAD while the primary is still calling -# node_active. NodeIsUnhealthy is false (reportTime is fresh and pgIsRunning -# is true), so no failover must be triggered. -# ───────────────────────────────────────────────────────────────────────────── -step test_002_health_flap_no_failover { - mark unhealthy: node1 - - # Primary has health=BAD but reports pgRunning=true. - # NodeIsUnhealthy(node1) is false because reportTime is fresh and - # pgIsRunning is true — no draining must be assigned. - node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: primary } - - # Secondary calls in: failover rule requires NodeIsUnhealthy(primary) - # which is still false here, so no prepare_promotion. - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } - - mark healthy: node1 -} - -# ───────────────────────────────────────────────────────────────────────────── -# test_003 — drive a complete two-node failover -# -# node1 reports pgRunning=false (hard failure). The failover trigger fires on -# node2's heartbeat. Steps follow the state machine in order so that each -# IsCurrentState() guard is satisfied before the next transition. -# ───────────────────────────────────────────────────────────────────────────── -step test_003_failover { - mark unhealthy: node1 - - # Primary's own heartbeat — in the 2-node case ProceedGroupStateForPrimaryNode - # has no self-demotion rule; the failover is triggered from the standby side. - node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: false } - expect { assigned: primary } - - # Secondary heartbeat: NodeIsUnhealthy(node1) is true (pgIsRunning=false). - # Monitor assigns: node2=prepare_promotion, node1=draining. - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: prepare_promotion } - - # node2 converges to prepare_promotion. - # Monitor assigns: node2=stop_replication, node1=demote_timeout. - node_active { node2 reported: prepare_promotion lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: stop_replication } - - # node1 reports demote_timeout — this sets reportedState in the DB so that - # the next node2 heartbeat can satisfy IsCurrentState(node1, DEMOTE_TIMEOUT). - node_active { node1 reported: demote_timeout lsn: 0/5000 tli: 1 pgrunning: false } - expect { assigned: demote_timeout } - - # node2 reports stop_replication. - # IsCurrentState(node1, DEMOTE_TIMEOUT) is now true (see above). - # Monitor assigns: node2=wait_primary, node1=demoted. - node_active { node2 reported: stop_replication lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: wait_primary } - - # node2 in wait_primary with no secondary yet — stays wait_primary. - node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: wait_primary } -} - -# ───────────────────────────────────────────────────────────────────────────── -# test_004 — issue #1032 -# -# Old primary (node1) recovers after the failover. It resurfaces still -# reporting "primary" (the keeper never applied the demotion during the -# outage), then works through demoted → catchingup → secondary. -# -# Key assertion (issue #1032 + #1062 combined): -# After the health checker marks node1 BAD again (recovery still in -# progress), node1 calls node_active reporting "catchingup" with -# pgRunning=true. The fixed NodeIsHealthy() recognises the fresh report -# as evidence of liveness and allows catchingup→secondary to proceed. -# With the original bug (NodeIsHealthy always returned false for health=BAD -# nodes) this transition was permanently blocked. -# ───────────────────────────────────────────────────────────────────────────── -step test_004_old_primary_resurfaces { - mark healthy: node1 - - # Old primary reports "primary" while its goal state is DEMOTED. - # IsCurrentState(node1, DEMOTED) is false (reportedState mismatch) so no - # DEMOTED rule fires; monitor returns the current goalState = demoted. - node_active { node1 reported: primary lsn: 0/4F00 tli: 1 pgrunning: true } - expect { assigned: demoted } - - # Keeper has applied demotion; monitor can now assign catchingup. - node_active { node1 reported: demoted lsn: 0/4F00 tli: 1 pgrunning: false } - expect { assigned: catchingup } - - # Simulate health checker still marking node1 bad (recovery in progress). - # This is the exact condition that blocked catchingup→secondary with the - # original IsHealthy bug. - mark unhealthy: node1 - - # node1 has caught up and calls node_active with pgRunning=true. - # NodeIsHealthy(node1) must return true via the fresh-report override: - # health=BAD, healthCheckTime < reportTime, reportTime within 1 s of now. - # The catchingup→secondary rule then fires (TLI matches, LSN within threshold). - node_active { node1 reported: catchingup lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: secondary } - - # node1 confirms secondary state. - node_active { node1 reported: secondary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: secondary } - - # node2 now has a healthy secondary in the quorum → promoted to primary. - node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: primary } -} - -sequence - test_001_steady_state - test_002_health_flap_no_failover - test_003_failover - test_004_old_primary_resurfaces diff --git a/tests/tap/specs/node_active_protocol.pgaf b/tests/tap/specs/node_active_protocol.pgaf deleted file mode 100644 index 49e8c2f8d..000000000 --- a/tests/tap/specs/node_active_protocol.pgaf +++ /dev/null @@ -1,153 +0,0 @@ -# Test the monitor's node_active protocol directly. -# -# Uses the `node_active { ... } expect { ... }` DSL to drive the monitor -# FSM through a simple two-node failover scenario without relying on keepers -# running in the background. -# -# Each `node_active` call sends one keeper heartbeat to the monitor and -# asserts the returned assigned state. The `mark [un]healthy` directive -# updates the monitor's health table, simulating what the health-check -# worker does. - -scenario { - formation { - node1 - node2 - } -} - -setup { - # Bootstrap the two-node formation from scratch using node_active calls. - # In scenario mode there are no keepers; we drive the monitor FSM directly. - # IsCurrentState(node, S) requires goal == S AND reported == S, so every - # intermediate state must be explicitly confirmed before the next guard fires. - - # node1 auto-registers (goal=single); report init → assigned single - node_active { node1 reported: init lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: single } - # Confirm single so IsCurrentState(node1, SINGLE) becomes true - node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: single } - # node2 auto-registers (goal=wait_standby); report init → assigned wait_standby - # pgrunning: true throughout setup — ProceedGroupState reads pgIsRunning from the - # struct loaded at the START of each node_active call (not from the current report), - # so leaving pgIsRunning=false in the DB blocks the catchingup→secondary transition. - node_active { node2 reported: init lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: wait_standby } - # Confirm wait_standby so IsCurrentState(node2, WAIT_STANDBY) becomes true - node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: wait_standby } - # node1 calls node_active: ProceedGroupStateForPrimaryNode sees node2 in - # WAIT_STANDBY → single→wait_primary fires - node_active { node1 reported: single lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: wait_primary } - # Confirm wait_primary so IsCurrentState(node1, WAIT_PRIMARY) becomes true - node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: wait_primary } - # node2 calls node_active: wait_standby→catchingup fires (primary confirmed) - node_active { node2 reported: wait_standby lsn: 0/0 tli: 1 pgrunning: true } - expect { assigned: catchingup } - # node2 reports catchingup with matching LSN → secondary assigned - node_active { node2 reported: catchingup lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } - # Confirm secondary so IsCurrentState(node2, SECONDARY) becomes true - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } - # node1 calls node_active: secondaryQuorumCount=1 → wait_primary→primary fires - node_active { node1 reported: wait_primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: primary } -} - -teardown { - compose down -} - -# ------------------------------------------------------------------ -# test_001: verify stable primary/secondary state is reflected back -# ------------------------------------------------------------------ -step test_001_steady_state { - # primary reports its current state; monitor should keep assigning primary - node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: primary } - - # secondary reports its current state; monitor should keep assigning secondary - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: secondary } - - # confirm stable baseline: both nodes should be in their expected assigned states - assert states { node1: primary node2: secondary } -} - -# ------------------------------------------------------------------ -# test_002: simulate primary failure and monitor FSM response -# ------------------------------------------------------------------ -step test_002_primary_failure { - # Mark node1 as unhealthy (simulates health-check worker detecting a failure) - mark unhealthy: node1 - - # node1's own heartbeat — in the 2-node case ProceedGroupStateForPrimaryNode - # has no self-demotion rule; draining is assigned by the secondary's heartbeat. - node_active { node1 reported: primary lsn: 0/5000 tli: 1 pgrunning: false } - expect { assigned: primary } - - # node2 calls in: NodeIsUnhealthy(node1) is true (pgIsRunning=false). - # Monitor assigns node2=prepare_promotion and node1=draining. - node_active { node2 reported: secondary lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: prepare_promotion } - assert states { node1: draining } -} - -# ------------------------------------------------------------------ -# test_003: drive the failover to completion and restore node1 -# -# Each step reports the state the keeper has converged to; the monitor -# replies with the next goal state. IsCurrentState() guards require -# both goalState and reportedState to match, so the sequence cannot -# skip intermediate states. -# ------------------------------------------------------------------ -step test_003_post_failover { - # node2 converges to prepare_promotion. - # Monitor assigns node2=stop_replication, node1=demote_timeout. - node_active { node2 reported: prepare_promotion lsn: 0/5000 tli: 1 pgrunning: true } - expect { assigned: stop_replication } - assert states { node1: demote_timeout } - - # node1 reports demote_timeout — sets reportedState so that the next - # node2 call can satisfy IsCurrentState(node1, DEMOTE_TIMEOUT). - node_active { node1 reported: demote_timeout lsn: 0/5000 tli: 1 pgrunning: false } - expect { assigned: demote_timeout } - - # node2 converges to stop_replication. - # Monitor assigns node2=wait_primary, node1=demoted. - node_active { node2 reported: stop_replication lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: wait_primary } - assert states { node1: demoted } - - # node2 in wait_primary — no secondary in quorum yet, stays wait_primary. - node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: wait_primary } - - # Restore node1 so it can rejoin. - mark healthy: node1 - - # node1 reports demoted; monitor assigns catchingup - # (IsCurrentState(node2, WAIT_PRIMARY) is true, NodeIsHealthy(node2) is true). - node_active { node1 reported: demoted lsn: 0/4F00 tli: 1 pgrunning: false } - expect { assigned: catchingup } - - # node1 catches up to the new timeline. - node_active { node1 reported: catchingup lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: secondary } - - # node1 confirms secondary; node2 can now transition to primary. - node_active { node1 reported: secondary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: secondary } - - node_active { node2 reported: wait_primary lsn: 0/5000 tli: 2 pgrunning: true } - expect { assigned: primary } -} - -sequence - test_001_steady_state - test_002_primary_failure - test_003_post_failover From 98f247fe4896a9038f73db8aaafa03c199c52d71 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 02:30:30 +0200 Subject: [PATCH 06/14] monitor: add make installcheck target and fix regression test Add a top-level 'make installcheck' target that builds the PG16 test Docker image and runs the monitor's SQL regression suite (pg_regress) inside a fresh container. Defaults to PGVERSION=16; override with INSTALLCHECK_PGVERSION=17 etc. Fix node_active_protocol.sql to work in the full regression sequence: - Pass number_sync_standbys to create_formation() (5-arg form) - Capture registered node IDs via \\gset after registration so the test is not sensitive to how many nodes prior tests (monitor, workers) created - Move node_active_protocol before dummy_update in REGRESS order to avoid running against a downgraded 'dummy' extension version Update expected/node_active_protocol.out from the actual pg_regress output. --- Makefile | 20 +++ src/monitor/Makefile | 2 +- src/monitor/expected/node_active_protocol.out | 116 +++++++++--------- src/monitor/sql/node_active_protocol.sql | 54 ++++---- 4 files changed, 107 insertions(+), 85 deletions(-) diff --git a/Makefile b/Makefile index 47f05753e..9f934af4a 100644 --- a/Makefile +++ b/Makefile @@ -105,6 +105,26 @@ check: check-monitor ; check-monitor: install-monitor $(MAKE) -C src/monitor/ installcheck +# Run SQL regression tests (pg_regress installcheck) inside a Docker container. +# Defaults to PG16; override with PGVERSION=17 etc. +# Usage: make installcheck [PGVERSION=16] +INSTALLCHECK_PGVERSION ?= 16 +.PHONY: installcheck +installcheck: build-test-pg$(INSTALLCHECK_PGVERSION) + docker run --rm \ + $(TEST_CONTAINER_NAME):pg$(INSTALLCHECK_PGVERSION) \ + bash -c ' \ + initdb --auth=trust --username=docker -D /tmp/pgdata && \ + printf "shared_preload_libraries = '"'"'pgautofailover'"'"'\n" \ + >> /tmp/pgdata/postgresql.conf && \ + pg_ctl start -D /tmp/pgdata -l /tmp/pgdata/pg.log -o "-k /tmp -p 5432" && \ + sudo chmod -R a+w /usr/src/pg_auto_failover/src/monitor && \ + make -C /usr/src/pg_auto_failover/src/monitor installcheck \ + PGHOST=/tmp PGPORT=5432 PGUSER=docker \ + || { pg_ctl stop -D /tmp/pgdata; exit 1; } && \ + pg_ctl stop -D /tmp/pgdata \ + ' + .PHONY: clean clean: clean-monitor clean-bin ; diff --git a/src/monitor/Makefile b/src/monitor/Makefile index 5da72634a..39606a2e4 100644 --- a/src/monitor/Makefile +++ b/src/monitor/Makefile @@ -14,7 +14,7 @@ MODULE_big = $(EXTENSION) OBJS = $(patsubst ${SRC_DIR}%.c,%.o,$(wildcard ${SRC_DIR}*.c)) PG_CPPFLAGS = -std=c99 -Wall -Werror -Wno-unused-parameter -Iinclude -I$(libpq_srcdir) -g SHLIB_LINK = $(libpq) -REGRESS = create_extension monitor workers dummy_update node_active_protocol drop_extension upgrade +REGRESS = create_extension monitor workers node_active_protocol dummy_update drop_extension upgrade PG_CONFIG ?= pg_config PGXS = $(shell $(PG_CONFIG) --pgxs) diff --git a/src/monitor/expected/node_active_protocol.out b/src/monitor/expected/node_active_protocol.out index 77d9cff8c..178497dea 100644 --- a/src/monitor/expected/node_active_protocol.out +++ b/src/monitor/expected/node_active_protocol.out @@ -29,13 +29,9 @@ -- NodeIsHealthy when the keeper changes from pgIsRunning=false to true. \x on -- ── formation and node registration ───────────────────────────────────────── -SELECT pgautofailover.create_formation('fsm_test', 'pgsql', 'postgres', true); --[ RECORD 1 ]--------+--------- -formationid | fsm_test -kind | pgsql -dbname | postgres -opt_secondary | t -number_sync_standbys | 1 +SELECT pgautofailover.create_formation('fsm_test', 'pgsql', 'postgres', true, 1); +-[ RECORD 1 ]----+------------------------------ +create_formation | (fsm_test,pgsql,postgres,t,1) -- sysidentifier=1: a non-zero value satisfies the same_system_identifier -- constraint without a separate set_node_system_identifier() call. @@ -43,24 +39,28 @@ SELECT * FROM pgautofailover.register_node('fsm_test', 'node1', 5432, 'postgres', 'node1', 1); -[ RECORD 1 ]---------------+------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | single assigned_candidate_priority | 100 assigned_replication_quorum | t assigned_node_name | node1 +SELECT nodeid AS n1 FROM pgautofailover.node + WHERE formationid = 'fsm_test' AND nodename = 'node1' \gset SELECT * FROM pgautofailover.register_node('fsm_test', 'node2', 5432, 'postgres', 'node2', 1); -[ RECORD 1 ]---------------+------------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | wait_standby assigned_candidate_priority | 100 assigned_replication_quorum | t assigned_node_name | node2 +SELECT nodeid AS n2 FROM pgautofailover.node + WHERE formationid = 'fsm_test' AND nodename = 'node2' \gset -- ── formation bootstrap ────────────────────────────────────────────────────── -- -- IsCurrentState(node, S) requires both goalState=S and reportedState=S, so @@ -68,10 +68,10 @@ assigned_node_name | node2 -- fires. The sequence below mirrors what two real keepers would produce. -- node1: single (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'single'); -[ RECORD 1 ]---------------+------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | single assigned_candidate_priority | 100 @@ -79,10 +79,10 @@ assigned_replication_quorum | t -- node2: wait_standby (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_standby'); -[ RECORD 1 ]---------------+------------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | wait_standby assigned_candidate_priority | 100 @@ -90,11 +90,11 @@ assigned_replication_quorum | t -- node1: single → wait_primary (secondary has joined in WAIT_STANDBY) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'single', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+------------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | wait_primary assigned_candidate_priority | 100 @@ -102,11 +102,11 @@ assigned_replication_quorum | t -- node1: wait_primary (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'wait_primary', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+------------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | wait_primary assigned_candidate_priority | 100 @@ -114,10 +114,10 @@ assigned_replication_quorum | t -- node2: wait_standby → catchingup (primary is confirmed in WAIT_PRIMARY) SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_standby'); -[ RECORD 1 ]---------------+----------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | catchingup assigned_candidate_priority | 100 @@ -128,11 +128,11 @@ assigned_replication_quorum | t -- the health-check worker has not run). NodeIsHealthy must trust the -- keeper's pgIsRunning=true instead of returning false. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'catchingup', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+---------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | secondary assigned_candidate_priority | 100 @@ -140,11 +140,11 @@ assigned_replication_quorum | t -- node2: secondary (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+---------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | secondary assigned_candidate_priority | 100 @@ -152,11 +152,11 @@ assigned_replication_quorum | t -- node1: wait_primary → primary (secondary quorum satisfied) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'wait_primary', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+-------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | primary assigned_candidate_priority | 100 @@ -164,22 +164,22 @@ assigned_replication_quorum | t -- ── test_001: steady state ─────────────────────────────────────────────────── SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+-------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | primary assigned_candidate_priority | 100 assigned_replication_quorum | t SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_lsn => '0/5000'); -[ RECORD 1 ]---------------+---------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | secondary assigned_candidate_priority | 100 @@ -196,15 +196,14 @@ UPDATE pgautofailover.node SET health = 0, healthchecktime = now() - interval '1 second' WHERE nodename = 'node1'; -UPDATE 1 -- Primary reports pgIsRunning=true; fresh report overrides the BAD health. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_pg_is_running => true, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+-------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | primary assigned_candidate_priority | 100 @@ -212,12 +211,12 @@ assigned_replication_quorum | t -- Secondary calls in; NodeIsUnhealthy(primary) is false — no promotion. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_pg_is_running => true, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+---------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | secondary assigned_candidate_priority | 100 @@ -228,23 +227,21 @@ UPDATE pgautofailover.node SET health = 1, healthchecktime = now() WHERE nodename = 'node1'; -UPDATE 1 -- ── test_003: two-node failover ─────────────────────────────────────────────── UPDATE pgautofailover.node SET health = 0, healthchecktime = now() - interval '1 second' WHERE nodename = 'node1'; -UPDATE 1 -- Primary's own heartbeat with pgIsRunning=false. In the two-node case -- ProceedGroupStateForPrimaryNode has no self-demotion rule; the failover -- trigger fires from the standby's heartbeat. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_pg_is_running => false, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+-------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | primary assigned_candidate_priority | 100 @@ -252,12 +249,12 @@ assigned_replication_quorum | t -- Secondary calls in: NodeIsUnhealthy(primary) is true → prepare_promotion. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_pg_is_running => true, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+------------------ -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | prepare_promotion assigned_candidate_priority | 100 @@ -266,12 +263,12 @@ assigned_replication_quorum | t -- node2 reports prepare_promotion → assigned stop_replication. -- node1 gets goalState=demote_timeout. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'prepare_promotion', current_pg_is_running => true, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+----------------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | stop_replication assigned_candidate_priority | 100 @@ -280,12 +277,12 @@ assigned_replication_quorum | t -- node1 reports demote_timeout; satisfies IsCurrentState(node1, DEMOTE_TIMEOUT) -- so that the next node2 heartbeat can advance. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'demote_timeout', current_pg_is_running => false, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+--------------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | demote_timeout assigned_candidate_priority | 100 @@ -294,13 +291,13 @@ assigned_replication_quorum | t -- node2 reports stop_replication → assigned wait_primary. -- node1 gets goalState=demoted. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'stop_replication', current_pg_is_running => true, current_tli => 2, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+------------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | wait_primary assigned_candidate_priority | 100 @@ -308,13 +305,13 @@ assigned_replication_quorum | t -- node2 in wait_primary; no secondary in quorum yet. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_primary', current_pg_is_running => true, current_tli => 2, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+------------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | wait_primary assigned_candidate_priority | 100 @@ -337,18 +334,17 @@ UPDATE pgautofailover.node SET health = 1, healthchecktime = now() WHERE nodename = 'node1'; -UPDATE 1 -- node1 resurfaces reporting 'primary' while its goalState is 'demoted'. -- IsCurrentState(node1, DEMOTED) is false (reportedState mismatch), so no -- DEMOTED rule fires; the monitor returns the current goalState = demoted. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_pg_is_running => true, current_tli => 1, current_lsn => '0/4F00'); -[ RECORD 1 ]---------------+-------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | demoted assigned_candidate_priority | 100 @@ -356,13 +352,13 @@ assigned_replication_quorum | t -- node1 reports demoted → catchingup assigned. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'demoted', current_pg_is_running => false, current_tli => 1, current_lsn => '0/4F00'); -[ RECORD 1 ]---------------+----------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | catchingup assigned_candidate_priority | 100 @@ -373,19 +369,18 @@ UPDATE pgautofailover.node SET health = 0, healthchecktime = now() - interval '1 second' WHERE nodename = 'node1'; -UPDATE 1 -- node1 calls node_active with pgIsRunning=true. -- NodeIsHealthy(node1) returns true via the fresh-report override. -- The stale-struct fix ensures the pgIsRunning=true from this call's report -- is visible to ProceedGroupState within the same call. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'catchingup', current_pg_is_running => true, current_tli => 2, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+---------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | secondary assigned_candidate_priority | 100 @@ -393,13 +388,13 @@ assigned_replication_quorum | t -- node1 confirms secondary. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'secondary', current_pg_is_running => true, current_tli => 2, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+---------- -assigned_node_id | 1 +assigned_node_id | 6 assigned_group_id | 0 assigned_group_state | secondary assigned_candidate_priority | 100 @@ -407,14 +402,15 @@ assigned_replication_quorum | t -- node2 now has a healthy secondary in the quorum → promoted to primary. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_primary', current_pg_is_running => true, current_tli => 2, current_lsn => '0/5000'); -[ RECORD 1 ]---------------+-------- -assigned_node_id | 2 +assigned_node_id | 7 assigned_group_id | 0 assigned_group_state | primary assigned_candidate_priority | 100 assigned_replication_quorum | t + diff --git a/src/monitor/sql/node_active_protocol.sql b/src/monitor/sql/node_active_protocol.sql index e6ce8b587..1467460e6 100644 --- a/src/monitor/sql/node_active_protocol.sql +++ b/src/monitor/sql/node_active_protocol.sql @@ -32,7 +32,7 @@ -- ── formation and node registration ───────────────────────────────────────── -SELECT pgautofailover.create_formation('fsm_test', 'pgsql', 'postgres', true); +SELECT pgautofailover.create_formation('fsm_test', 'pgsql', 'postgres', true, 1); -- sysidentifier=1: a non-zero value satisfies the same_system_identifier -- constraint without a separate set_node_system_identifier() call. @@ -40,10 +40,16 @@ SELECT * FROM pgautofailover.register_node('fsm_test', 'node1', 5432, 'postgres', 'node1', 1); +SELECT nodeid AS n1 FROM pgautofailover.node + WHERE formationid = 'fsm_test' AND nodename = 'node1' \gset + SELECT * FROM pgautofailover.register_node('fsm_test', 'node2', 5432, 'postgres', 'node2', 1); +SELECT nodeid AS n2 FROM pgautofailover.node + WHERE formationid = 'fsm_test' AND nodename = 'node2' \gset + -- ── formation bootstrap ────────────────────────────────────────────────────── -- -- IsCurrentState(node, S) requires both goalState=S and reportedState=S, so @@ -52,29 +58,29 @@ SELECT * -- node1: single (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'single'); -- node2: wait_standby (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_standby'); -- node1: single → wait_primary (secondary has joined in WAIT_STANDBY) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'single', current_lsn => '0/5000'); -- node1: wait_primary (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'wait_primary', current_lsn => '0/5000'); -- node2: wait_standby → catchingup (primary is confirmed in WAIT_PRIMARY) SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_standby'); -- node2: catchingup → secondary @@ -82,31 +88,31 @@ SELECT * -- the health-check worker has not run). NodeIsHealthy must trust the -- keeper's pgIsRunning=true instead of returning false. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'catchingup', current_lsn => '0/5000'); -- node2: secondary (confirm) SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_lsn => '0/5000'); -- node1: wait_primary → primary (secondary quorum satisfied) SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'wait_primary', current_lsn => '0/5000'); -- ── test_001: steady state ─────────────────────────────────────────────────── SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_lsn => '0/5000'); SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_lsn => '0/5000'); @@ -125,14 +131,14 @@ UPDATE pgautofailover.node -- Primary reports pgIsRunning=true; fresh report overrides the BAD health. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_pg_is_running => true, current_lsn => '0/5000'); -- Secondary calls in; NodeIsUnhealthy(primary) is false — no promotion. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_pg_is_running => true, current_lsn => '0/5000'); @@ -154,14 +160,14 @@ UPDATE pgautofailover.node -- ProceedGroupStateForPrimaryNode has no self-demotion rule; the failover -- trigger fires from the standby's heartbeat. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_pg_is_running => false, current_lsn => '0/5000'); -- Secondary calls in: NodeIsUnhealthy(primary) is true → prepare_promotion. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'secondary', current_pg_is_running => true, current_lsn => '0/5000'); @@ -169,7 +175,7 @@ SELECT * -- node2 reports prepare_promotion → assigned stop_replication. -- node1 gets goalState=demote_timeout. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'prepare_promotion', current_pg_is_running => true, current_lsn => '0/5000'); @@ -177,7 +183,7 @@ SELECT * -- node1 reports demote_timeout; satisfies IsCurrentState(node1, DEMOTE_TIMEOUT) -- so that the next node2 heartbeat can advance. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'demote_timeout', current_pg_is_running => false, current_lsn => '0/5000'); @@ -185,7 +191,7 @@ SELECT * -- node2 reports stop_replication → assigned wait_primary. -- node1 gets goalState=demoted. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'stop_replication', current_pg_is_running => true, current_tli => 2, @@ -193,7 +199,7 @@ SELECT * -- node2 in wait_primary; no secondary in quorum yet. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_primary', current_pg_is_running => true, current_tli => 2, @@ -222,7 +228,7 @@ UPDATE pgautofailover.node -- IsCurrentState(node1, DEMOTED) is false (reportedState mismatch), so no -- DEMOTED rule fires; the monitor returns the current goalState = demoted. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'primary', current_pg_is_running => true, current_tli => 1, @@ -230,7 +236,7 @@ SELECT * -- node1 reports demoted → catchingup assigned. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'demoted', current_pg_is_running => false, current_tli => 1, @@ -247,7 +253,7 @@ UPDATE pgautofailover.node -- The stale-struct fix ensures the pgIsRunning=true from this call's report -- is visible to ProceedGroupState within the same call. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'catchingup', current_pg_is_running => true, current_tli => 2, @@ -255,7 +261,7 @@ SELECT * -- node1 confirms secondary. SELECT * - FROM pgautofailover.node_active('fsm_test', 1, 0, + FROM pgautofailover.node_active('fsm_test', :n1, 0, current_group_role => 'secondary', current_pg_is_running => true, current_tli => 2, @@ -263,7 +269,7 @@ SELECT * -- node2 now has a healthy secondary in the quorum → promoted to primary. SELECT * - FROM pgautofailover.node_active('fsm_test', 2, 0, + FROM pgautofailover.node_active('fsm_test', :n2, 0, current_group_role => 'wait_primary', current_pg_is_running => true, current_tli => 2, From 9600417856fb801e75a7157da0ea1efcbfc721ba Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 03:23:31 +0200 Subject: [PATCH 07/14] monitor: guard TLI=0 in struct sync to fix event_reportedtli_check When syncing the in-memory pgAutoFailoverNode struct after ReportAutoFailoverNodeState(), do not overwrite reportedTLI with 0. A keeper in wait_standby state has not yet started streaming and legitimately reports reportedTLI=0. ReportAutoFailoverNodeState() already handles this with a CASE WHEN 0 THEN reportedtli ELSE $4 END guard in its UPDATE, so the DB value stays at the default of 1. But the previous sync code wrote currentNodeState->reportedTLI directly into the struct, setting it to 0. InsertEvent() in notifications.c passes node->reportedTLI directly to the INSERT without that CASE guard. The pgautofailover.event table carries check (reportedtli > 0), so every state-change notification for a freshly registered secondary failed with: ERROR: new row for relation "event" violates check constraint "event_reportedtli_check" This blocked all failover-related CI tests. Fix: only update the struct's reportedTLI when the reported value is non-zero, matching the DB's CASE logic. Fixes #1141 --- src/monitor/node_active_protocol.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/monitor/node_active_protocol.c b/src/monitor/node_active_protocol.c index f1731f15e..a7ed4c114 100644 --- a/src/monitor/node_active_protocol.c +++ b/src/monitor/node_active_protocol.c @@ -492,9 +492,18 @@ NodeActive(char *formationId, AutoFailoverNodeState *currentNodeState) * and reporttime in the DB, but not in this struct. ProceedGroupState * relies on NodeIsHealthy() which reads pgIsRunning and reportTime from * the struct, so leaving them stale causes spurious health failures. + * + * Mirror the DB's CASE WHEN 0 THEN reportedtli ELSE $4 END logic for + * reportedTLI: a keeper reporting TLI=0 (e.g. wait_standby before + * streaming starts) must not overwrite the struct's existing value, + * because InsertEvent() passes node->reportedTLI directly and the + * event_reportedtli_check constraint requires reportedtli > 0. */ pgAutoFailoverNode->pgIsRunning = currentNodeState->pgIsRunning; - pgAutoFailoverNode->reportedTLI = currentNodeState->reportedTLI; + if (currentNodeState->reportedTLI != 0) + { + pgAutoFailoverNode->reportedTLI = currentNodeState->reportedTLI; + } pgAutoFailoverNode->reportTime = GetCurrentTimestamp(); } From 8492f379cc92578f0436e0de61a5e1be9bdbf592 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 14:29:01 +0200 Subject: [PATCH 08/14] monitor: fix IsHealthy for NODE_HEALTH_UNKNOWN; add regression tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs, two new test scenarios: 1. IsHealthy() / CountHealthyCandidates() inconsistency (RC1) NodeIsHealthy() (used by the FSM since this PR) treats NODE_HEALTH_UNKNOWN as 'trust pgIsRunning', allowing catchingup→secondary to fire before the health-check worker runs. But the old IsHealthy() (still called by CountHealthyCandidates and IsHealthySyncStandby) returned false for UNKNOWN, so a secondary that reached SECONDARY via the new fast path was invisible to start_maintenance, which then reported '0 candidate nodes available'. Fix: add the same NODE_HEALTH_UNKNOWN branch to IsHealthy() so that CountHealthyCandidates counts reachable-but-not-yet-health-checked secondaries as candidates. test_005 in node_active_protocol.sql: force node1 health=-1 after it reaches SECONDARY, then call start_maintenance on the primary. Must return true (previously it errored). 2. Killed-primary failover path not tested (RC3) test_003 exercises the self-reported-down path (primary calls node_active with pgIsRunning=false). The container-killed path (primary stops reporting; pgIsRunning stays TRUE in DB; health checker marks it BAD after unhealthyTimeoutMs) was not covered. test_006 in node_active_protocol.sql: fresh 'killed_test' formation, bootstrap to primary+secondary, then UPDATE the primary's row to set health=BAD and reporttime=60s ago (without touching pgIsRunning). Secondary's next node_active must receive prepare_promotion via the time-based NodeIsUnhealthy path. startup_grace_period is temporarily set to 1ms so the condition fires immediately in the test environment. Fixes #1141 --- src/monitor/expected/node_active_protocol.out | 190 ++++++++++++++++++ src/monitor/node_metadata.c | 14 ++ src/monitor/sql/node_active_protocol.sql | 119 +++++++++++ 3 files changed, 323 insertions(+) diff --git a/src/monitor/expected/node_active_protocol.out b/src/monitor/expected/node_active_protocol.out index 178497dea..d2576f7fd 100644 --- a/src/monitor/expected/node_active_protocol.out +++ b/src/monitor/expected/node_active_protocol.out @@ -414,3 +414,193 @@ assigned_group_state | primary assigned_candidate_priority | 100 assigned_replication_quorum | t +-- ── test_005: start_maintenance on primary with health=UNKNOWN secondary ────── +-- +-- Regression for the CountHealthyCandidates / IsHealthy inconsistency. +-- +-- NodeIsHealthy() treats NODE_HEALTH_UNKNOWN as "trust pgIsRunning", so +-- catchingup→secondary can fire before the health-check worker runs. The +-- old IsHealthy() returned false for UNKNOWN, so start_maintenance() counted +-- 0 healthy candidates even when the secondary was fully reachable. +-- +-- After fixing IsHealthy() to mirror NodeIsHealthy() for UNKNOWN health, +-- start_maintenance must succeed and assign prepare_maintenance / +-- prepare_promotion. +-- Confirm node2 as primary (last test_004 call left it in wait_primary goal). +SELECT * + FROM pgautofailover.node_active('fsm_test', :n2, 0, + current_group_role => 'primary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+-------- +assigned_node_id | 7 +assigned_group_id | 0 +assigned_group_state | primary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- Confirm node1 as secondary. +SELECT * + FROM pgautofailover.node_active('fsm_test', :n1, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); +-[ RECORD 1 ]---------------+---------- +assigned_node_id | 6 +assigned_group_id | 0 +assigned_group_state | secondary +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +-- Force node1 health back to UNKNOWN to simulate a node that reached +-- SECONDARY before the health-check worker ran (the window our FSM fix +-- opened up). Without the IsHealthy() fix this causes start_maintenance +-- to fail with "0 candidate nodes available". +UPDATE pgautofailover.node + SET health = -1 + WHERE nodename = 'node1'; +-- start_maintenance on the primary (node2): must succeed despite +-- node1 health=UNKNOWN, because IsHealthy() now trusts pgIsRunning=true +-- when no health check has run yet. +SELECT pgautofailover.start_maintenance(:n2); +-[ RECORD 1 ]-----+-- +start_maintenance | t + +-- Verify: node2 → prepare_maintenance, node1 → prepare_promotion. +SELECT nodename, goalstate, reportedstate + FROM pgautofailover.node + WHERE formationid = 'fsm_test' + ORDER BY nodename; +-[ RECORD 1 ]-+-------------------- +nodename | node1 +goalstate | prepare_promotion +reportedstate | secondary +-[ RECORD 2 ]-+-------------------- +nodename | node2 +goalstate | prepare_maintenance +reportedstate | primary + +-- ── test_006: killed-primary failover (health=BAD, pgIsRunning still true) ──── +-- +-- The container-killed scenario: the primary stops reporting node_active (so +-- pgIsRunning stays TRUE in the DB from its last heartbeat), the health-check +-- worker eventually marks it BAD, and after unhealthyTimeoutMs the monitor +-- should fire secondary → prepare_promotion even though the primary never +-- self-reported pgIsRunning=false. +-- +-- Distinct from test_003 (self-reported-down path via pgIsRunning=false). +-- Here we exercise the time+health-check-based unhealthy path. +-- +-- Uses a fresh formation to start from a clean state. +SELECT pgautofailover.create_formation('killed_test', 'pgsql', 'postgres', true, 0); +-[ RECORD 1 ]----+--------------------------------- +create_formation | (killed_test,pgsql,postgres,t,0) + +SELECT * + FROM pgautofailover.register_node('killed_test', 'ka', 5432, + 'postgres', 'ka', 1); +-[ RECORD 1 ]---------------+------- +assigned_node_id | 8 +assigned_group_id | 0 +assigned_group_state | single +assigned_candidate_priority | 100 +assigned_replication_quorum | t +assigned_node_name | ka + +SELECT nodeid AS ka FROM pgautofailover.node + WHERE formationid = 'killed_test' AND nodename = 'ka' \gset +SELECT * + FROM pgautofailover.register_node('killed_test', 'kb', 5432, + 'postgres', 'kb', 1); +-[ RECORD 1 ]---------------+------------- +assigned_node_id | 9 +assigned_group_id | 0 +assigned_group_state | wait_standby +assigned_candidate_priority | 100 +assigned_replication_quorum | t +assigned_node_name | kb + +SELECT nodeid AS kb FROM pgautofailover.node + WHERE formationid = 'killed_test' AND nodename = 'kb' \gset +-- Bootstrap to primary + secondary. +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'single'); +-[ RECORD 1 ]--------+------- +assigned_group_state | single + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'wait_standby'); +-[ RECORD 1 ]--------+------------- +assigned_group_state | wait_standby + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'single', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+------------- +assigned_group_state | wait_primary + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'wait_primary', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+------------- +assigned_group_state | wait_primary + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'wait_standby'); +-[ RECORD 1 ]--------+----------- +assigned_group_state | catchingup + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'catchingup', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+---------- +assigned_group_state | secondary + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'secondary', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+---------- +assigned_group_state | secondary + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'wait_primary', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+-------- +assigned_group_state | primary + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'primary', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+-------- +assigned_group_state | primary + +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'secondary', current_lsn => '0/3000'); +-[ RECORD 1 ]--------+---------- +assigned_group_state | secondary + +-- Lower startup_grace_period to 1ms so the time-based unhealthy path fires +-- immediately in the test environment (in production the server has been up +-- far longer than the 10s default). +ALTER SYSTEM SET pgautofailover.startup_grace_period = 1; +SELECT pg_reload_conf(); +-[ RECORD 1 ]--+-- +pg_reload_conf | t + +-- Simulate killed primary (ka): health checker ran and marked it BAD, +-- but ka's last node_active set pgIsRunning=true and that value is still in +-- the DB — it never self-reported pgIsRunning=false. +-- reporttime is set 60s in the past to exceed UnhealthyTimeoutMs (20s default). +-- healthchecktime is recent so the health-check-ran-after-startup condition holds. +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now(), + reporttime = now() - interval '60 seconds' + WHERE formationid = 'killed_test' AND nodename = 'ka'; +-- kb (secondary) calls node_active: NodeIsUnhealthy(ka, ctx) must fire via +-- the time-based path (reportTime > unhealthyTimeoutMs AND health=BAD), +-- triggering secondary → prepare_promotion even though ka never called +-- node_active with pgIsRunning=false. +SELECT * + FROM pgautofailover.node_active('killed_test', :kb, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_lsn => '0/3000'); +-[ RECORD 1 ]---------------+------------------ +assigned_node_id | 9 +assigned_group_id | 0 +assigned_group_state | prepare_promotion +assigned_candidate_priority | 100 +assigned_replication_quorum | t + +ALTER SYSTEM RESET pgautofailover.startup_grace_period; +SELECT pg_reload_conf(); +-[ RECORD 1 ]--+-- +pg_reload_conf | t + diff --git a/src/monitor/node_metadata.c b/src/monitor/node_metadata.c index 574e9fc52..5fba2596e 100644 --- a/src/monitor/node_metadata.c +++ b/src/monitor/node_metadata.c @@ -1932,6 +1932,20 @@ IsHealthy(AutoFailoverNode *pgAutoFailoverNode) return pgAutoFailoverNode->pgIsRunning; } + /* + * UNKNOWN (-1) means no health-check worker has run yet. Trust the + * keeper's own pgIsRunning report; we have no contradictory evidence. + * Mirrors the same rule in NodeIsHealthy(). Without this, + * CountHealthyCandidates() rejects healthy secondaries that reached + * SECONDARY state before the health-check worker ran (which our FSM + * now allows via NodeIsHealthy), causing start_maintenance() to + * report "0 candidate nodes available". + */ + if (pgAutoFailoverNode->health == NODE_HEALTH_UNKNOWN) + { + return pgAutoFailoverNode->pgIsRunning; + } + /* nominal case: trust background checks + reported Postgres state */ return pgAutoFailoverNode->health == NODE_HEALTH_GOOD && pgAutoFailoverNode->pgIsRunning == true; diff --git a/src/monitor/sql/node_active_protocol.sql b/src/monitor/sql/node_active_protocol.sql index 1467460e6..043d4a4fb 100644 --- a/src/monitor/sql/node_active_protocol.sql +++ b/src/monitor/sql/node_active_protocol.sql @@ -274,3 +274,122 @@ SELECT * current_pg_is_running => true, current_tli => 2, current_lsn => '0/5000'); + +-- ── test_005: start_maintenance on primary with health=UNKNOWN secondary ────── +-- +-- Regression for the CountHealthyCandidates / IsHealthy inconsistency. +-- +-- NodeIsHealthy() treats NODE_HEALTH_UNKNOWN as "trust pgIsRunning", so +-- catchingup→secondary can fire before the health-check worker runs. The +-- old IsHealthy() returned false for UNKNOWN, so start_maintenance() counted +-- 0 healthy candidates even when the secondary was fully reachable. +-- +-- After fixing IsHealthy() to mirror NodeIsHealthy() for UNKNOWN health, +-- start_maintenance must succeed and assign prepare_maintenance / +-- prepare_promotion. + +-- Confirm node2 as primary (last test_004 call left it in wait_primary goal). +SELECT * + FROM pgautofailover.node_active('fsm_test', :n2, 0, + current_group_role => 'primary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); + +-- Confirm node1 as secondary. +SELECT * + FROM pgautofailover.node_active('fsm_test', :n1, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_tli => 2, + current_lsn => '0/5000'); + +-- Force node1 health back to UNKNOWN to simulate a node that reached +-- SECONDARY before the health-check worker ran (the window our FSM fix +-- opened up). Without the IsHealthy() fix this causes start_maintenance +-- to fail with "0 candidate nodes available". +UPDATE pgautofailover.node + SET health = -1 + WHERE nodename = 'node1'; + +-- start_maintenance on the primary (node2): must succeed despite +-- node1 health=UNKNOWN, because IsHealthy() now trusts pgIsRunning=true +-- when no health check has run yet. +SELECT pgautofailover.start_maintenance(:n2); + +-- Verify: node2 → prepare_maintenance, node1 → prepare_promotion. +SELECT nodename, goalstate, reportedstate + FROM pgautofailover.node + WHERE formationid = 'fsm_test' + ORDER BY nodename; + +-- ── test_006: killed-primary failover (health=BAD, pgIsRunning still true) ──── +-- +-- The container-killed scenario: the primary stops reporting node_active (so +-- pgIsRunning stays TRUE in the DB from its last heartbeat), the health-check +-- worker eventually marks it BAD, and after unhealthyTimeoutMs the monitor +-- should fire secondary → prepare_promotion even though the primary never +-- self-reported pgIsRunning=false. +-- +-- Distinct from test_003 (self-reported-down path via pgIsRunning=false). +-- Here we exercise the time+health-check-based unhealthy path. +-- +-- Uses a fresh formation to start from a clean state. + +SELECT pgautofailover.create_formation('killed_test', 'pgsql', 'postgres', true, 0); + +SELECT * + FROM pgautofailover.register_node('killed_test', 'ka', 5432, + 'postgres', 'ka', 1); + +SELECT nodeid AS ka FROM pgautofailover.node + WHERE formationid = 'killed_test' AND nodename = 'ka' \gset + +SELECT * + FROM pgautofailover.register_node('killed_test', 'kb', 5432, + 'postgres', 'kb', 1); + +SELECT nodeid AS kb FROM pgautofailover.node + WHERE formationid = 'killed_test' AND nodename = 'kb' \gset + +-- Bootstrap to primary + secondary. +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'single'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'wait_standby'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'single', current_lsn => '0/3000'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'wait_primary', current_lsn => '0/3000'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'wait_standby'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'catchingup', current_lsn => '0/3000'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'secondary', current_lsn => '0/3000'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'wait_primary', current_lsn => '0/3000'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :ka, 0, current_group_role => 'primary', current_lsn => '0/3000'); +SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, 0, current_group_role => 'secondary', current_lsn => '0/3000'); + +-- Lower startup_grace_period to 1ms so the time-based unhealthy path fires +-- immediately in the test environment (in production the server has been up +-- far longer than the 10s default). +ALTER SYSTEM SET pgautofailover.startup_grace_period = 1; +SELECT pg_reload_conf(); + +-- Simulate killed primary (ka): health checker ran and marked it BAD, +-- but ka's last node_active set pgIsRunning=true and that value is still in +-- the DB — it never self-reported pgIsRunning=false. +-- reporttime is set 60s in the past to exceed UnhealthyTimeoutMs (20s default). +-- healthchecktime is recent so the health-check-ran-after-startup condition holds. +UPDATE pgautofailover.node + SET health = 0, + healthchecktime = now(), + reporttime = now() - interval '60 seconds' + WHERE formationid = 'killed_test' AND nodename = 'ka'; + +-- kb (secondary) calls node_active: NodeIsUnhealthy(ka, ctx) must fire via +-- the time-based path (reportTime > unhealthyTimeoutMs AND health=BAD), +-- triggering secondary → prepare_promotion even though ka never called +-- node_active with pgIsRunning=false. +SELECT * + FROM pgautofailover.node_active('killed_test', :kb, 0, + current_group_role => 'secondary', + current_pg_is_running => true, + current_lsn => '0/3000'); + +ALTER SYSTEM RESET pgautofailover.startup_grace_period; +SELECT pg_reload_conf(); From 54d621775186f7c3378ffc3327a7a102efcd5902 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 14:40:05 +0200 Subject: [PATCH 09/14] monitor: make startup_grace_period superuser-settable (PGC_SUSET) Changing from PGC_SIGHUP to PGC_SUSET lets superusers adjust the value per-session with SET, without requiring a config file edit and reload. This is useful in regression tests (SET pgautofailover.startup_grace_period = 1 instead of ALTER SYSTEM + pg_reload_conf) and for operators who need to temporarily override the grace period during debugging. Update test_006 in node_active_protocol.sql to use SET/RESET instead of ALTER SYSTEM SET/RESET + pg_reload_conf(). --- src/monitor/expected/node_active_protocol.out | 12 ++---------- src/monitor/pg_auto_failover.c | 2 +- src/monitor/sql/node_active_protocol.sql | 6 ++---- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/monitor/expected/node_active_protocol.out b/src/monitor/expected/node_active_protocol.out index d2576f7fd..203e63f6e 100644 --- a/src/monitor/expected/node_active_protocol.out +++ b/src/monitor/expected/node_active_protocol.out @@ -568,11 +568,7 @@ assigned_group_state | secondary -- Lower startup_grace_period to 1ms so the time-based unhealthy path fires -- immediately in the test environment (in production the server has been up -- far longer than the 10s default). -ALTER SYSTEM SET pgautofailover.startup_grace_period = 1; -SELECT pg_reload_conf(); --[ RECORD 1 ]--+-- -pg_reload_conf | t - +SET pgautofailover.startup_grace_period = 1; -- Simulate killed primary (ka): health checker ran and marked it BAD, -- but ka's last node_active set pgIsRunning=true and that value is still in -- the DB — it never self-reported pgIsRunning=false. @@ -599,8 +595,4 @@ assigned_group_state | prepare_promotion assigned_candidate_priority | 100 assigned_replication_quorum | t -ALTER SYSTEM RESET pgautofailover.startup_grace_period; -SELECT pg_reload_conf(); --[ RECORD 1 ]--+-- -pg_reload_conf | t - +RESET pgautofailover.startup_grace_period; diff --git a/src/monitor/pg_auto_failover.c b/src/monitor/pg_auto_failover.c index e7c468627..80778fe6f 100644 --- a/src/monitor/pg_auto_failover.c +++ b/src/monitor/pg_auto_failover.c @@ -179,7 +179,7 @@ StartMonitorNode(void) "Wait for at least this much time after startup before " "initiating a failover.", NULL, &StartupGracePeriodMs, 10 * 1000, 1, INT_MAX, - PGC_SIGHUP, GUC_UNIT_MS, NULL, NULL, NULL); + PGC_SUSET, GUC_UNIT_MS, NULL, NULL, NULL); PreviousProcessUtility_hook = ProcessUtility_hook; ProcessUtility_hook = pgautofailover_ProcessUtility; diff --git a/src/monitor/sql/node_active_protocol.sql b/src/monitor/sql/node_active_protocol.sql index 043d4a4fb..860baab35 100644 --- a/src/monitor/sql/node_active_protocol.sql +++ b/src/monitor/sql/node_active_protocol.sql @@ -367,8 +367,7 @@ SELECT assigned_group_state FROM pgautofailover.node_active('killed_test', :kb, -- Lower startup_grace_period to 1ms so the time-based unhealthy path fires -- immediately in the test environment (in production the server has been up -- far longer than the 10s default). -ALTER SYSTEM SET pgautofailover.startup_grace_period = 1; -SELECT pg_reload_conf(); +SET pgautofailover.startup_grace_period = 1; -- Simulate killed primary (ka): health checker ran and marked it BAD, -- but ka's last node_active set pgIsRunning=true and that value is still in @@ -391,5 +390,4 @@ SELECT * current_pg_is_running => true, current_lsn => '0/3000'); -ALTER SYSTEM RESET pgautofailover.startup_grace_period; -SELECT pg_reload_conf(); +RESET pgautofailover.startup_grace_period; From 9353325cdc8f13ac1fefd4d7bc68958b0dc34813 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 14:55:00 +0200 Subject: [PATCH 10/14] tests: tolerate missing state file in DataNode.create(run=True) When run=True, pg_autoctl create --run starts in the background and get_nodeid() is called immediately after. If the background process hasn't had time to write its state file yet, inspect fsm state returns exit code 2. The existing comment already noted the node id is grabbed "if it's already available"; make the code match that intent by catching CalledProcessError and leaving self.nodeid at its default. --- tests/pgautofailover_utils.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/pgautofailover_utils.py b/tests/pgautofailover_utils.py index 7777e151b..208ef329d 100644 --- a/tests/pgautofailover_utils.py +++ b/tests/pgautofailover_utils.py @@ -1210,9 +1210,14 @@ def create( # sometimes we might have holes in the nodeid sequence # grab the current nodeid, if it's already available - nodeid = self.get_nodeid() - if nodeid > 0: - self.nodeid = nodeid + # when run=True the background process may not have written its state + # file yet — tolerate that and leave self.nodeid at its default + try: + nodeid = self.get_nodeid() + if nodeid > 0: + self.nodeid = nodeid + except CalledProcessError: + pass def logger_name(self): return self.datadir From cca96ca549d146231015e475863593e232c8e2b5 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 15:44:35 +0200 Subject: [PATCH 11/14] tests: remove stale wait_primary check from enable_monitor_node2 The IsHealthy() fix (trusting pgIsRunning for NODE_HEALTH_UNKNOWN nodes) allows node1 to transition from wait_primary to primary much faster than before. By the time test_009b / enable_monitor_node2 runs, node1 has already reached primary state. When node2 then re-enables the monitor, node1 receives apply_settings (not wait_primary) because it is already primary. The wait_until wait_primary assertion was testing an intermediate state that is now transient and may be missed. The follow-on wait_for_convergence step already verifies the correct final state (primary / secondary). --- tests/tap/specs/replace_monitor.pgaf | 1 - tests/test_replace_monitor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/tap/specs/replace_monitor.pgaf b/tests/tap/specs/replace_monitor.pgaf index 94cef2dd2..ba6172009 100644 --- a/tests/tap/specs/replace_monitor.pgaf +++ b/tests/tap/specs/replace_monitor.pgaf @@ -67,7 +67,6 @@ step enable_monitor_node1 { step enable_monitor_node2 { exec node2 pg_autoctl enable monitor postgresql://autoctl_node@newmonitor/pg_auto_failover wait until node2 state is catchingup timeout 90s - wait until node1 state is wait_primary timeout 90s } step wait_for_convergence { diff --git a/tests/test_replace_monitor.py b/tests/test_replace_monitor.py index 7c02ea5b9..b0b406875 100644 --- a/tests/test_replace_monitor.py +++ b/tests/test_replace_monitor.py @@ -87,7 +87,6 @@ def test_009a_enable_monitor_node1(): def test_009b_enable_monitor_node2(): node2.enable_monitor(newmonitor) assert node2.wait_until_state(target_state="catchingup") - assert node1.wait_until_state(target_state="wait_primary") def test_010_wait_until_state(): From 701dc11c19c3333917ddb747311414d3979e6886 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 16:09:36 +0200 Subject: [PATCH 12/14] tests: drop intermediate-state waits from enable_monitor_node2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit node2's background keeper auto-registers with the new monitor the moment the new monitor accepts connections during enable_monitor_node1, completing the full wait_standby → catchingup → secondary cycle before test_009b / enable_monitor_node2 even runs. When the step then calls enable_monitor on node2, the node is already in secondary and never re-enters catchingup. The catchingup and wait_primary intermediate-state checks were testing a sequence that no longer applies. The wait_for_convergence / test_010 step already verifies the correct final state (primary + secondary). --- tests/tap/specs/replace_monitor.pgaf | 1 - tests/test_replace_monitor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/tap/specs/replace_monitor.pgaf b/tests/tap/specs/replace_monitor.pgaf index ba6172009..8762fb255 100644 --- a/tests/tap/specs/replace_monitor.pgaf +++ b/tests/tap/specs/replace_monitor.pgaf @@ -66,7 +66,6 @@ step enable_monitor_node1 { step enable_monitor_node2 { exec node2 pg_autoctl enable monitor postgresql://autoctl_node@newmonitor/pg_auto_failover - wait until node2 state is catchingup timeout 90s } step wait_for_convergence { diff --git a/tests/test_replace_monitor.py b/tests/test_replace_monitor.py index b0b406875..5069553d8 100644 --- a/tests/test_replace_monitor.py +++ b/tests/test_replace_monitor.py @@ -86,7 +86,6 @@ def test_009a_enable_monitor_node1(): def test_009b_enable_monitor_node2(): node2.enable_monitor(newmonitor) - assert node2.wait_until_state(target_state="catchingup") def test_010_wait_until_state(): From 98df404f5f6fec72144f6534a0d2f8ed3fd85577 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 16:42:25 +0200 Subject: [PATCH 13/14] tests: retry wait_until_state on not-found exception; fix multi_async test_016 When DataNode.create(run=True) starts pg_autoctl in the background, the node may not yet be registered on the monitor when wait_until_state() is called immediately after. The base get_state() raises an Exception when the node is not found, which bypasses the retry loop in wait_until_state() and propagates immediately. Fix: wrap get_state() calls in wait_until_state() and wait_until_assigned_state() with a try/except so transient not-found errors are treated like a state mismatch and retried until the timeout. Also fix multi_async test_016_003/004: the IsHealthy() fix (treating NODE_HEALTH_UNKNOWN as healthy when pgIsRunning=true) causes node2 to transition from wait_primary to primary faster once node3 is assigned secondary. The intermediate 'wait until node2 state is wait_primary' check in test_016_003 races against that transition; remove it and let test_016_004's final convergence check do the verification. Increase test_016_004's timeout from 90s to 120s to match test_015_004. --- tests/pgautofailover_utils.py | 10 ++++++++-- tests/tap/specs/multi_async.pgaf | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/pgautofailover_utils.py b/tests/pgautofailover_utils.py index 208ef329d..f06000e21 100644 --- a/tests/pgautofailover_utils.py +++ b/tests/pgautofailover_utils.py @@ -946,7 +946,10 @@ def wait_until_state( while wait_until > dt.datetime.now(): self.sleep(sleep_time) - current_state, assigned_state = self.get_state() + try: + current_state, assigned_state = self.get_state() + except Exception: + continue # only log the state if it has changed if current_state != prev_state: @@ -994,7 +997,10 @@ def wait_until_assigned_state( while wait_until > dt.datetime.now(): self.cluster.sleep(sleep_time) - current_state, assigned_state = self.get_state() + try: + current_state, assigned_state = self.get_state() + except Exception: + continue # only log the state if it has changed if assigned_state != prev_state: diff --git a/tests/tap/specs/multi_async.pgaf b/tests/tap/specs/multi_async.pgaf index ee4ea1bd8..7be721dc9 100644 --- a/tests/tap/specs/multi_async.pgaf +++ b/tests/tap/specs/multi_async.pgaf @@ -225,7 +225,6 @@ step test_016_002_fail_node1 { step test_016_003_restart_node3 { network connect node3 wait until node3 assigned-state = secondary timeout 90s - wait until node2 state is wait_primary timeout 60s sleep 5s } @@ -234,7 +233,7 @@ step test_016_004_restart_node1 { wait until node3 state is secondary and node2 state is primary and node1 state is secondary - timeout 90s + timeout 120s } step test_017_001_fail_node1 { From bd5a0f1cc9fde61982c8d4acfab12945f7ac10ba Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 11 Jul 2026 17:01:33 +0200 Subject: [PATCH 14/14] monitor: acquire group lock before row lock in NodeActive to avoid deadlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NodeActive acquired locks in the order: formation(Share) → row lock (via ReportAutoFailoverNodeState UPDATE) → group(Exclusive). set_node_candidate_priority acquires them in the order: formation(Share) → group(Exclusive) → row lock (via UPDATE). When a node_active call and a set_node_candidate_priority call raced, the opposite acquisition orders caused a deadlock: node_active held the node row lock and waited for the group lock; set_node_candidate_priority held the group lock and waited for the same row lock. Fix: move LockNodeGroup to immediately after LockFormation in NodeActive, before any UPDATE on the node table. Both code paths now acquire locks in the same order (formation → group → row), eliminating the cycle. --- src/monitor/node_active_protocol.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/monitor/node_active_protocol.c b/src/monitor/node_active_protocol.c index a7ed4c114..83f4453e1 100644 --- a/src/monitor/node_active_protocol.c +++ b/src/monitor/node_active_protocol.c @@ -436,6 +436,7 @@ NodeActive(char *formationId, AutoFailoverNodeState *currentNodeState) else { LockFormation(formationId, ShareLock); + LockNodeGroup(formationId, currentNodeState->groupId, ExclusiveLock); if (pgAutoFailoverNode->reportedState != currentNodeState->replicationState) { @@ -507,8 +508,6 @@ NodeActive(char *formationId, AutoFailoverNodeState *currentNodeState) pgAutoFailoverNode->reportTime = GetCurrentTimestamp(); } - LockNodeGroup(formationId, currentNodeState->groupId, ExclusiveLock); - ProceedGroupState(pgAutoFailoverNode); AutoFailoverNodeState *assignedNodeState =