2016-11-03 3 views
0

fread()에 대한 호출이 많이 있습니다.C의 fread() 오류에 대한 테스트 케이스

반환 값은 읽은 바이트 수를 확인하고 0, 에 도달하면 파일/스트림 끝에 도달했음을 의미합니다.

이제는 완전히 정확하지 않습니다. 오류가 발생하면 fread()0을 반환 할 수 있습니다. 해당 상태를 확인하는 방법은 예를 들어 feof()으로 전화하는 것입니다.

fread()이 호출되는 모든 곳에서 모든 테스트를 확실히 추가 할 수 있습니다. 그러나 그것은 요점이 아닙니다. 그것은 일종의 "시각 장애"일 것입니다. 문제를 관찰하고 반복하기 위해 테스트 케이스가 필요하며 CI 테스트의 일부로 수정 사항을 관찰하십시오.

지금까지 아무 것도 발견하지 못했습니다. fwrite()에 대한 문제가 비교적 적지 만, fread()에 대해서는 에도 영향을 미치지 않고 신뢰할 수있는 방법을 찾지 못했습니다.fopen()과 완전히 다른 상황이 이미 테스트되었습니다.

모든 의견을 환영합니다.

+4

일반 파일의 읽기 오류는 발생하기가 쉽지 않으므로 대개 디스크 오류가 발생합니다. 오류를 유발할 수있는 수정 된 라이브러리와 링크해야 할 수도 있습니다. – Barmar

+2

'feof()'는 파일 끝이 감지되면보고하고, fread()는 0을 반환하면 feof()가 "오류가 발생했습니다"라는 표시가 아니어야합니다. 'ferror()'를 사용하여 "오류가 발생했는지"를 탐지하십시오. – chux

답변

1

견고한 표준 솔루션이 없습니다.

C는 오류를 시뮬레이트하거나 심지어 FILE*오류 표시기을 설정하는 명확한 방법을 제공하지 않습니다.

테스트 코드는 컴파일러/플랫폼에 따라 FILE오류 표시기을 설정할 수 있습니다. 아마 간단한 대안

#define SIM_ERROR(stream, ret) \ 
    while (1) {if (my_rand()==0) { (stream)_flags |= __SERR; (ret) = 0;} } 

ret = fread(ptr, size, nmemb, stream); 
SIM_ERROR(stream, ret); 

, 약간 더 휴대용 접근법 등. 코드는 테스트 중에 표준 라이브러리에 대한 임시 교체로 자체 기능을 사용하여 오류를 일으킬 수 있습니다.

int my_error_indicator = 0; 
intptr_t my_stream = 0; 

size_t my_fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream) { 
    if (rand() == 0) { 
    my_error_indicator = 1; 
    my_stream = (intptr_t) stream; 
    return 0; 
    } 
    return fread(ptr, size, nmemb, stream); 
} 

int my_ferror(FILE *stream) { 
    if (my_error_indicator && (intptr_t) stream == my_stream) { 
    return my_error_indicator; 
    } 
    return ferror(stream); 
} 

void my_clearerr(FILE *stream) { 
    if ((intptr_t) stream == my_stream) { 
    my_stream = NULL; 
    my_error_indicator = 0; 
    } 
    clearerr(stream); 
} 

#define fread my_fread 
#define ferror my_ferror 
#define clearerr my_clearerr 

교체 fclose(), rewind() 그들이 드 할당 및/또는 오류 표시를 지우 너무으로 필요하다.

여러 스트림의 오류는 여기에서 처리되지 않습니다.

+0

제안 해 주셔서 감사합니다. 이는 일반적으로 내가 피하려고하는 복잡성의 종류이지만 때로는 ... – Cyan

+0

@Cyan 언젠가, 아마도 너무 자주 테스트 코드가 테스트중인 코드의 크기와 복잡성을 초과 할 수 있습니다. 그렇다면 테스트 코드를 테스트하는 코드는 무엇이라고 말합니까? 흠? – chux

+0

긴 테스트 코드는 중요하지 않습니다. 당신이 말했듯이, 그것은 드물지 않습니다. "중간에 삽입하는"것에 더 관심이 있습니다. 기본적으로 가짜 반환 값을 푸시하여 사용 사례를 발명했습니다. 유효/대표자가 그러한 테스트인지 확실하지 않습니다.확실히 아무것도 아닌 것보다 낫습니다. fread()/ferror()가 자신감을 얻는 방법을 충분히 모르는 경우 일 수 있습니다. 경험은 신중함을 배웁니다. – Cyan

관련 문제