END_TEST START_TEST(test_trace_read_deposits) { int status = trace_open("test/4_2_10.trace"); ck_assert_msg(status != -1, "trace_open should not return -1 if the file does exists"); Command cmd; int deposits = 0; cmd_t c; int i, f, t, a; while (trace_read_cmd(&cmd) != 0) { cmd_unpack(&cmd, &c, &i, &f, &t, &a); switch (c) { case DEPOSIT: deposits++; break; } } ck_assert_msg(deposits == 2, "there should be 2 deposit messages, received %d", deposits); trace_close(); }
END_TEST START_TEST(test_trace_read_transfers) { int status = trace_open("test/4_2_10.trace"); ck_assert_msg(status != -1, "trace_open should not return -1 if the file does exists"); Command cmd; int transfers = 0; cmd_t c; int i, f, t, a; while (trace_read_cmd(&cmd) != 0) { cmd_unpack(&cmd, &c, &i, &f, &t, &a); switch (c) { case TRANSFER: transfers++; break; } } ck_assert_msg(transfers == 4, "there should be 4 transfer message, received %d", transfers); trace_close(); }
END_TEST START_TEST(test_trace_read_balances) { int status = trace_open("test/4_2_10.trace"); ck_assert_msg(status != -1, "trace_open should not return -1 if the file does exists"); Command cmd; int balances = 0; cmd_t c; int i, f, t, a; while (trace_read_cmd(&cmd) != 0) { cmd_unpack(&cmd, &c, &i, &f, &t, &a); switch (c) { case BALANCE: balances++; break; } } ck_assert_msg(balances == 3, "there should be 3 balance messages, received %d", balances); trace_close(); }
END_TEST START_TEST(test_trace_read_valid_commands) { int status = trace_open("test/4_2_10.trace"); ck_assert_msg(status != -1, "trace_open should not return -1 if the file does exists"); Command cmd; cmd_t c; int i, f, t, a; while (trace_read_cmd(&cmd) != 0) { cmd_unpack(&cmd, &c, &i, &f, &t, &a); switch (c) { case CONNECT: case EXIT: case DEPOSIT: case WITHDRAW: case TRANSFER: case BALANCE: break; default: ck_abort_msg("expected valid command, received %d", c); } } trace_close(); }
END_TEST START_TEST(test_atm_balance_success) { // The file descriptors used for writing to the bank process and // reading in from the atm process. int bankfd[2]; pipe(bankfd); int atmfd[2]; pipe(atmfd); int bank_read = bankfd[0]; int bank_write = bankfd[1]; int atm_read = atmfd[0]; int atm_write = atmfd[1]; // The command buffer. Command cmd; MSG_BALANCE(&cmd, 0, 1); if (fork() == 0) { // Send it to the atm. int status = atm(bank_write, atm_read, 0, &cmd); ck_assert_msg(status == SUCCESS, "status should be SUCCESS, received %d", status); } else { // Need to set the read end of pipe to non-blocking otherwise // students without an implementation will not be able to run // tests. int flags = fcntl(bank_read, F_GETFL, 0); fcntl(bank_read, F_SETFL, flags | O_NONBLOCK); sleep(1); int status = read(bank_read, &cmd, MESSAGE_SIZE); ck_assert_msg(status != -1, "ATM should have sent data to the bank"); cmd_t c; int i, f, t, a; cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == BALANCE, "received message should be balance, got %d", c); ck_assert_int_eq(i, 0); ck_assert_int_eq(f, 1); ck_assert_int_eq(t, -1); ck_assert_int_eq(a, -1); MSG_OK(&cmd, i, f, t, a); write(atm_write, &cmd, MESSAGE_SIZE); } // Close file descriptors. close(bankfd[0]); close(bankfd[1]); close(atmfd[0]); close(atmfd[1]); }
END_TEST START_TEST(test_trace_read_single_cmd) { int status = trace_open("test/4_2_10.trace"); ck_assert_msg(status != -1, "trace_open should not return -1 if the file does exists"); Command cmd; trace_read_cmd(&cmd); cmd_t c; int i, f, t, a; cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == CONNECT, "first command should be CONNECT, received %d", c); }
END_TEST START_TEST(test_command_balance) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_BALANCE(&cmd, i, f); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == BALANCE, "command should be balance, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == 2, "f should be 2, received %d", f); ck_assert_msg(t == -1, "t should be -1, received %d", t); ck_assert_msg(a == -1, "a should be -1, received %d", a); }
END_TEST START_TEST(test_command_transfer) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_TRANSFER(&cmd, i, f, t, a); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == TRANSFER, "command should be ok, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == 2, "f should be 2, received %d", f); ck_assert_msg(t == 3, "t should be 3, received %d", t); ck_assert_msg(a == 4, "a should be 4, received %d", a); }
END_TEST START_TEST(test_command_withdraw) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_WITHDRAW(&cmd, i, f, a); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == WITHDRAW, "command should be withdraw, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == 2, "f should be 2, received %d", f); ck_assert_msg(t == -1, "t should be -1, received %d", t); ck_assert_msg(a == 4, "a should be 4, received %d", a); }
END_TEST START_TEST(test_command_deposit) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_DEPOSIT(&cmd, i, t, a); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == DEPOSIT, "command should be deposit, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == -1, "f should be -1, received %d", f); ck_assert_msg(t == 3, "t should be 3, received %d", t); ck_assert_msg(a == 4, "a should be 4, received %d", a); }
END_TEST START_TEST(test_command_connect) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_CONNECT(&cmd, i); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == CONNECT, "command should be connect, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == -1, "f should be -1, received %d", f); ck_assert_msg(t == -1, "t should be -1, received %d", t); ck_assert_msg(a == -1, "a should be -1, received %d", a); }
END_TEST START_TEST(test_command_nofunds) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_NOFUNDS(&cmd, i, f, a); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == NOFUNDS, "command should be no funds, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == 2, "f should be 2, received %d", f); ck_assert_msg(t == -1, "t should be -1, received %d", t); ck_assert_msg(a == 4, "a should be 4, received %d", a); }
END_TEST START_TEST(test_atm_connect_success) { // The file descriptors used for writing to the bank process and // reading in from the atm process. int bankfd[2]; pipe(bankfd); int atmfd[2]; pipe(atmfd); int bank_read = bankfd[0]; int bank_write = bankfd[1]; int atm_read = atmfd[0]; int atm_write = atmfd[1]; // The command buffer. Command cmd; MSG_CONNECT(&cmd, 0); if (fork() == 0) { // Send it to the atm. int status = atm(bank_write, atm_read, 0, &cmd); ck_assert_msg(status == SUCCESS, "status should be SUCCESS, received %d", status); } else { int flags = fcntl(bank_read, F_GETFL, 0); fcntl(bank_read, F_SETFL, flags | O_NONBLOCK); sleep(1); int status = read(bank_read, &cmd, MESSAGE_SIZE); ck_assert_msg(status != -1, "ATM should have sent data to the bank"); cmd_t c; int i, f, t, a; cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == CONNECT, "received message should be connect, got %d", c); MSG_OK(&cmd, i, f, t, a); write(atm_write, &cmd, MESSAGE_SIZE); } // Close file descriptors. close(bankfd[0]); close(bankfd[1]); close(atmfd[0]); close(atmfd[1]); }
END_TEST ////////////////////////////////////////////////////////////////////// ///////////// bank unit tests ////////////////////////////////////////////////////////////////////// START_TEST(test_bank_connect) { int atmfd[2]; pipe(atmfd); int atm_read = atmfd[0]; int atm_write[1] = { atmfd[1] }; // The command buffer. Command cmd; if (fork() == 0) { bank_open(1, 1); MSG_CONNECT(&cmd, 0); int atm_cnt = 1; int status = bank(atm_write, &cmd, &atm_cnt); ck_assert_msg(status == SUCCESS, "status should be SUCCESS, received %d", status); bank_close(); } else { // Need to set the read end of pipe to non-blocking otherwise // students without an implementation will not be able to run // tests. int flags = fcntl(atm_read, F_GETFL, 0); fcntl(atm_read, F_SETFL, flags | O_NONBLOCK); sleep(1); int status = read(atm_read, &cmd, MESSAGE_SIZE); ck_assert_msg(status != -1, "BANK should have received data from the ATM"); cmd_t c; int i, f, t, a; cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == OK, "received message should be ok, got %d", c); ck_assert_int_eq(i, 0); ck_assert_int_eq(f, -1); ck_assert_int_eq(t, -1); ck_assert_int_eq(a, -1); } }
END_TEST ////////////////////////////////////////////////////////////////////// ///////////// command unit tests ////////////////////////////////////////////////////////////////////// START_TEST(test_command_ok) { Command cmd; cmd_t c; int i = 1, f = 2, t = 3, a = 4; MSG_OK(&cmd, i, f, t, a); cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == OK, "command should be ok, received %d", c); ck_assert_msg(i == 1, "i should be 1, received %d", i); ck_assert_msg(f == 2, "f should be 2, received %d", f); ck_assert_msg(t == 3, "t should be 3, received %d", t); ck_assert_msg(a == 4, "a should be 4, received %d", a); }
END_TEST START_TEST(test_bank_balance_bad_account) { int atmfd[2]; pipe(atmfd); int atm_write[1] = { atmfd[1] }; // The command buffer. Command cmd; if (fork() == 0) { bank_open(1, 1); int* accounts = get_accounts(); accounts[0] = 200; MSG_BALANCE(&cmd, 0, 1); int atm_cnt = 1; int status = bank(atm_write, &cmd, &atm_cnt); ck_assert_msg(status == SUCCESS, "status should be ERR_UNKNOWN_ACCOUNT, received %d", status); ck_assert_msg(accounts[0] == 200, "account should have 200, found %d", accounts[0]); bank_close(); } else { // Need to set the read end of pipe to non-blocking otherwise // students without an implementation will not be able to run // tests. int flags = fcntl(atmfd[0], F_GETFL, 0); fcntl(atmfd[0], F_SETFL, flags | O_NONBLOCK); sleep(1); int status = read(atmfd[0], &cmd, MESSAGE_SIZE); ck_assert_msg(status != -1, "ATM should have received data from the BANK"); cmd_t c; int i, f, t, a; cmd_unpack(&cmd, &c, &i, &f, &t, &a); ck_assert_msg(c == ACCUNKN, "bank should have sent ACCUNKN, received %d", c); } }
// The `atm` function processes commands received from a trace // file. It communicates to the bank transactions with a matching // ID. It then receives a response from the bank process and handles // the response appropriately. int atm(int bank_out_fd, int atm_in_fd, int atm_id, byte cmd[]) { byte c; int i,f,t,a; byte atmcmd[MESSAGE_SIZE]; cmd_unpack(cmd, &c, &i, &f, &t, &a); int status = SUCCESS; // TODO: // START YOUR IMPLEMENTATION if( i == atm_id){ if(c > 0 && c< 7){ //has to send connect first? /* if(c ==1){ MSG_CONNECT(cmd,i); } if(c==2){ MSG_EXIT(cmd,i); } if(c==3){ MSG_DEPOSIT(cmd, i ,t,a); } if(c==4){ MSG_WITHDRAW(cmd,i,f,a); } if(c==5){ MSG_TRANSFER(cmd,i,f,t,a); } if(c==6){ MSG_BALANCE(cmd,i,f); } */ status = write(bank_out_fd, cmd, MESSAGE_SIZE); if(check_pipe_write(status) != SUCCESS){ status = ERR_PIPE_WRITE_ERR; // printf("died here\n"); return status; } status = read(atm_in_fd,atmcmd, MESSAGE_SIZE); if(check_pipe_read(status) != SUCCESS){ status = ERR_PIPE_READ_ERR; // printf("dies here2\n"); return status; } cmd_unpack(atmcmd, &c, &i,&f,&t,&a); if(c == OK){ status = SUCCESS; } else if(c == NOFUNDS){ status = ERR_NOFUNDS ; } else if(c == ACCUNKN){ status = ERR_UNKNOWN_ACCOUNT; } else{ error_msg(ERR_UNKNOWN_CMD, "Unknown command!"); status = ERR_UNKNOWN_CMD; } } else{ error_msg(ERR_UNKNOWN_CMD,"uNKOWN"); status = ERR_UNKNOWN_CMD; } } else{ status = ERR_UNKNOWN_ATM ; // or 6 return status; } // END YOUR IMPLEMENTATION return status; }