Skip to content

Conversation

@ikerexxe
Copy link
Collaborator

@ikerexxe ikerexxe commented Mar 3, 2025

Testing for #1217

@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Mar 3, 2025

@alejandro-colomar this is the testing for #1217. It contains all your commits there + the implementation to run getent shadow $name from the test framework + the test themselves. Do you mind taking a look to the last commit and confirm that I have tested all possible cases? Nothing else came to my mind, but you might have additional ideas.

In addition, one of the test cases (usermod -e -1 $name) returns success (0) even though the expiration date wasn't changed. Do you mind taking a look at it? I think it's a failure in the code.

Finally, does the aforementioned PR also change the date behaviour for useradd and chage? If so, I'll add additional tests for them.

@alejandro-colomar
Copy link
Collaborator

alejandro-colomar commented Mar 3, 2025

@alejandro-colomar this is the testing for #1217. It contains all your commits there + the implementation to run getent shadow $name from the test framework + the test themselves. Do you mind taking a look to the last commit and confirm that I have tested all possible cases? Nothing else came to my mind, but you might have additional ideas.

In addition, one of the test cases (usermod -e -1 $name) returns success (0) even though the expiration date wasn't changed. Do you mind taking a look at it? I think it's a failure in the code.

I think I commented on the one you're mentioning. Was it that one that you were referring to?

Finally, does the aforementioned PR also change the date behaviour for useradd and chage? If so, I'll add additional tests for them.

It affects all of these (since I'm changing strtoday()):

$ grep -rli strtoday 
ChangeLog
src/usermod.c
src/useradd.c
src/chage.c
lib/prototypes.h
lib/strtoday.c
lib/Makefile.am
po/POTFILES.in
NEWS

@ikerexxe ikerexxe force-pushed the test-expiration-date branch 2 times, most recently from 9ea12c2 to 8a901b3 Compare March 4, 2025 12:02
@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Mar 4, 2025

@alejandro-colomar do you know why alpine fails when useradd/usermod/chage set the expiration date as YYYY-MM-DD? They all fail even though the date is valid (i.e. 2025-01-01).

@alejandro-colomar
Copy link
Collaborator

alejandro-colomar commented Mar 4, 2025

@alejandro-colomar do you know why alpine fails when useradd/usermod/chage set the expiration date as YYYY-MM-DD? They all fail even though the date is valid (i.e. 2025-01-01).

Is it a regression in my patches or is it a failure in master? Could you please open a PR without my changes, to test the tests against master?

@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Mar 4, 2025

It's also failing without your patches. You can set up an alpine container and check it there. Can this be related to the shell they are using? If I'm being honest my knowledge in that area is very limited.

@alejandro-colomar
Copy link
Collaborator

It's also failing without your patches. You can set up an alpine container and check it there. Can this be related to the shell they are using? If I'm being honest my knowledge in that area is very limited.

I don't know. It might be related to the signedness of time_t, or one of those little details. I'll check this weekend when I'm back home and have better internet to create the docker container and install all the deps.

@ikerexxe ikerexxe force-pushed the test-expiration-date branch from 8a901b3 to 3badae8 Compare March 27, 2025 10:45
@ikerexxe
Copy link
Collaborator Author

I don't know. It might be related to the signedness of time_t, or one of those little details. I'll check this weekend when I'm back home and have better internet to create the docker container and install all the deps.

@alejandro-colomar did you have time to look at this?

@alejandro-colomar
Copy link
Collaborator

I don't know. It might be related to the signedness of time_t, or one of those little details. I'll check this weekend when I'm back home and have better internet to create the docker container and install all the deps.

@alejandro-colomar did you have time to look at this?

I forgot. I'll try to do it today.

@alejandro-colomar
Copy link
Collaborator

alejandro-colomar commented Mar 27, 2025

@alejandro-colomar do you know why alpine fails when useradd/usermod/chage set the expiration date as YYYY-MM-DD? They all fail even though the date is valid (i.e. 2025-01-01).

I can't reproduce it.

I've run an alpine:latest container, installed all dependencies, git cloned and built shadow, and ran the following:

/shadow # ./src/useradd foo
/shadow # getent shadow foo
foo:!:20174::::::
/shadow # ./src/usermod -e '1970-10-20' foo
/shadow # getent shadow foo
foo:!:20174:::::292:
/shadow # ./src/usermod -e '1970-10-10' foo
/shadow # getent shadow foo
foo:!:20174:::::282:
/shadow # ./src/usermod -e '2025-01-01' foo
/shadow # getent shadow foo
foo:!:20174:::::20089:
/shadow # ./src/usermod -e '2125-01-01' foo
/shadow # getent shadow foo
foo:!:20174:::::56613:

It seems to be working as expected.

@ikerexxe
Copy link
Collaborator Author

Did you setup everything manually? I'm building the container using the automation:

$ ansible-playbook share/ansible/playbook.yml -i share/ansible/inventory.ini -e 'distribution=alpine'
...
$ podman exec -ti builder bash
# useradd tt
# getent shadow tt
tt:!:20174:0:99999:7:::
# usermod -e 10 tt
# getent shadow tt
tt:!:20174:0:99999:7::10:
# usermod -e 1970-10-20 tt
usermod: invalid date '1970-10-20'
# usermod -e '1970-10-20' tt
usermod: invalid date '1970-10-20'
# usermod -e "1970-10-20" tt
usermod: invalid date '1970-10-20'

@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Mar 27, 2025

It fails even with the default shell:

$ podman exec -ti builder sh
# usermod -e 1970-10-20 tt
usermod: invalid date '1970-10-20'

@alejandro-colomar
Copy link
Collaborator

Did you setup everything manually? I'm building the container using the automation:

$ ansible-playbook share/ansible/playbook.yml -i share/ansible/inventory.ini -e 'distribution=alpine'
...
$ podman exec -ti builder bash
# useradd tt
# getent shadow tt
tt:!:20174:0:99999:7:::
# usermod -e 10 tt
# getent shadow tt
tt:!:20174:0:99999:7::10:
# usermod -e 1970-10-20 tt
usermod: invalid date '1970-10-20'
# usermod -e '1970-10-20' tt
usermod: invalid date '1970-10-20'
# usermod -e "1970-10-20" tt
usermod: invalid date '1970-10-20'

Yep, everything manual. I'll try again with ansible.

@alejandro-colomar
Copy link
Collaborator

alejandro-colomar commented Mar 28, 2025

Did you setup everything manually? I'm building the container using the automation:

$ ansible-playbook share/ansible/playbook.yml -i share/ansible/inventory.ini -e 'distribution=alpine'
...
$ podman exec -ti builder bash
# useradd tt
# getent shadow tt
tt:!:20174:0:99999:7:::
# usermod -e 10 tt
# getent shadow tt
tt:!:20174:0:99999:7::10:
# usermod -e 1970-10-20 tt
usermod: invalid date '1970-10-20'
# usermod -e '1970-10-20' tt
usermod: invalid date '1970-10-20'
# usermod -e "1970-10-20" tt
usermod: invalid date '1970-10-20'

Yep, everything manual. I'll try again with ansible.

With ansible, it also works for me:

$ podman exec -ti builder bash
WARN[0000] Using cgroups-v1 which is deprecated in favor of cgroups-v2 with Podman v5 and will be removed in a future version. Set environment variable `PODMAN_IGNORE_CGROUPSV1_WARNING` to hide this warning. 
44da80a259d4:/# cat /etc/os-release 
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.21.3
PRETTY_NAME="Alpine Linux v3.21"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
44da80a259d4:/# ls
bin  etc   lib	  mnt  proc  run   srv	tmp  var
dev  home  media  opt  root  sbin  sys	usr
44da80a259d4:/# useradd tt
44da80a259d4:/# getent shadow tt
tt:!:20175:0:99999:7:::
44da80a259d4:/# usermod -e 10 tt
44da80a259d4:/# getent shadow tt
tt:!:20175:0:99999:7::10:
44da80a259d4:/# usermod -e 1970-10-20 tt
44da80a259d4:/# getent shadow tt
tt:!:20175:0:99999:7::292:
44da80a259d4:/# 

The bad thing about using ansible is that debugging becomes more difficult. I really preferred the old Dockerfiles.

@ikerexxe
Copy link
Collaborator Author

Ok, I've been able to reproduce the problem in a basic Alpine Linux container (no need to use ansible or build shadow) with the following reproducer:

#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <time.h>

int
main(void)
{
    struct tm tm;
    const char  *p;

    memset(&tm, 0, sizeof(tm));
    
    p = strptime("UTC", "%Z", &tm);
    if (p == NULL) {
    	printf("Error!\n");
        return -1;
    }
    
    printf("Success\n");
}

This code mimics in a very basic way get_date() function and it should return Error! but it should succeed. I guess musl doesn't implement strptime() completely 😞

@alejandro-colomar
Copy link
Collaborator

alejandro-colomar commented Mar 31, 2025

Ok, I've been able to reproduce the problem in a basic Alpine Linux container (no need to use ansible or build shadow) with the following reproducer:

#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <time.h>

int
main(void)
{
    struct tm tm;
    const char  *p;

    memset(&tm, 0, sizeof(tm));
    
    p = strptime("UTC", "%Z", &tm);
    if (p == NULL) {
    	printf("Error!\n");
        return -1;
    }
    
    printf("Success\n");
}

This code mimics in a very basic way get_date() function and it should return Error! but it should succeed. I guess musl doesn't implement strptime() completely 😞

musl seems to have a proper strptime(3), from what I can see in the source code. It must be an issue in Alpine, not musl.

Details
alx@devuan:~/src/musl/libc/master$ grepc strptime .
./include/time.h:char *strptime (const char *__restrict, const char *__restrict, struct tm *__restrict);
./src/time/strptime.c:char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
{
	int i, w, neg, adj, min, range, *dest, dummy;
	const char *ex;
	size_t len;
	int want_century = 0, century = 0, relyear = 0;
	while (*f) {
		if (*f != '%') {
			if (isspace(*f)) for (; *s && isspace(*s); s++);
			else if (*s != *f) return 0;
			else s++;
			f++;
			continue;
		}
		f++;
		if (*f == '+') f++;
		if (isdigit(*f)) {
			char *new_f;
			w=strtoul(f, &new_f, 10);
			f = new_f;
		} else {
			w=-1;
		}
		adj=0;
		switch (*f++) {
		case 'a': case 'A':
			dest = &tm->tm_wday;
			min = ABDAY_1;
			range = 7;
			goto symbolic_range;
		case 'b': case 'B': case 'h':
			dest = &tm->tm_mon;
			min = ABMON_1;
			range = 12;
			goto symbolic_range;
		case 'c':
			s = strptime(s, nl_langinfo(D_T_FMT), tm);
			if (!s) return 0;
			break;
		case 'C':
			dest = &century;
			if (w<0) w=2;
			want_century |= 2;
			goto numeric_digits;
		case 'd': case 'e':
			dest = &tm->tm_mday;
			min = 1;
			range = 31;
			goto numeric_range;
		case 'D':
			s = strptime(s, "%m/%d/%y", tm);
			if (!s) return 0;
			break;
		case 'F':
			/* Use temp buffer to implement the odd requirement
			 * that entire field be width-limited but the year
			 * subfield not itself be limited. */
			i = 0;
			char tmp[20];
			if (*s == '-' || *s == '+') tmp[i++] = *s++;
			while (*s=='0' && isdigit(s[1])) s++;
			for (; *s && i<(size_t)w && i+1<sizeof tmp; i++) {
				tmp[i] = *s++;
			}
			tmp[i] = 0;
			char *p = strptime(tmp, "%12Y-%m-%d", tm);
			if (!p) return 0;
			s -= tmp+i-p;
			break;
		case 'H':
			dest = &tm->tm_hour;
			min = 0;
			range = 24;
			goto numeric_range;
		case 'I':
			dest = &tm->tm_hour;
			min = 1;
			range = 12;
			goto numeric_range;
		case 'j':
			dest = &tm->tm_yday;
			min = 1;
			range = 366;
			adj = 1;
			goto numeric_range;
		case 'm':
			dest = &tm->tm_mon;
			min = 1;
			range = 12;
			adj = 1;
			goto numeric_range;
		case 'M':
			dest = &tm->tm_min;
			min = 0;
			range = 60;
			goto numeric_range;
		case 'n': case 't':
			for (; *s && isspace(*s); s++);
			break;
		case 'p':
			ex = nl_langinfo(AM_STR);
			len = strlen(ex);
			if (!strncasecmp(s, ex, len)) {
				tm->tm_hour %= 12;
				s += len;
				break;
			}
			ex = nl_langinfo(PM_STR);
			len = strlen(ex);
			if (!strncasecmp(s, ex, len)) {
				tm->tm_hour %= 12;
				tm->tm_hour += 12;
				s += len;
				break;
			}
			return 0;
		case 'r':
			s = strptime(s, nl_langinfo(T_FMT_AMPM), tm);
			if (!s) return 0;
			break;
		case 'R':
			s = strptime(s, "%H:%M", tm);
			if (!s) return 0;
			break;
		case 's':
			/* Parse only. Effect on tm is unspecified
			 * and presently no effect is implemented.. */
			if (*s == '-') s++;
			if (!isdigit(*s)) return 0;
			while (isdigit(*s)) s++;
			break;
		case 'S':
			dest = &tm->tm_sec;
			min = 0;
			range = 61;
			goto numeric_range;
		case 'T':
			s = strptime(s, "%H:%M:%S", tm);
			if (!s) return 0;
			break;
		case 'U':
		case 'W':
			/* Throw away result of %U, %V, %W, %g, and %G. Effect
			 * is unspecified and there is no clear right choice. */
			dest = &dummy;
			min = 0;
			range = 54;
			goto numeric_range;
		case 'V':
			dest = &dummy;
			min = 1;
			range = 53;
			goto numeric_range;
		case 'g':
			dest = &dummy;
			w = 2;
			goto numeric_digits;
		case 'G':
			dest = &dummy;
			if (w<0) w=4;
			goto numeric_digits;
		case 'u':
			dest = &tm->tm_wday;
			min = 1;
			range = 7;
			goto numeric_range;
		case 'w':
			dest = &tm->tm_wday;
			min = 0;
			range = 7;
			goto numeric_range;
		case 'x':
			s = strptime(s, nl_langinfo(D_FMT), tm);
			if (!s) return 0;
			break;
		case 'X':
			s = strptime(s, nl_langinfo(T_FMT), tm);
			if (!s) return 0;
			break;
		case 'y':
			dest = &relyear;
			w = 2;
			want_century |= 1;
			goto numeric_digits;
		case 'Y':
			dest = &tm->tm_year;
			if (w<0) w=4;
			adj = 1900;
			want_century = 0;
			goto numeric_digits;
		case 'z':
			if (*s == '+') neg = 0;
			else if (*s == '-') neg = 1;
			else return 0;
			for (i=0; i<4; i++) if (!isdigit(s[1+i])) return 0;
			tm->__tm_gmtoff = (s[1]-'0')*36000+(s[2]-'0')*3600
				+ (s[3]-'0')*600 + (s[4]-'0')*60;
			if (neg) tm->__tm_gmtoff = -tm->__tm_gmtoff;
			s += 5;
			break;
		case 'Z':
			if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) {
				tm->tm_isdst = 0;
				s += len;
			} else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) {
				tm->tm_isdst = 1;
				s += len;
			} else {
				/* FIXME: is this supposed to be an error? */
				while ((*s|32)-'a' <= 'z'-'a') s++;
			}
			break;
		case '%':
			if (*s++ != '%') return 0;
			break;
		default:
			return 0;
		numeric_range:
			if (!isdigit(*s)) return 0;
			*dest = 0;
			for (i=1; i<=min+range && isdigit(*s); i*=10)
				*dest = *dest * 10 + *s++ - '0';
			if (*dest - min >= (unsigned)range) return 0;
			*dest -= adj;
			switch((char *)dest - (char *)tm) {
			case offsetof(struct tm, tm_yday):
				;
			}
			goto update;
		numeric_digits:
			neg = 0;
			if (*s == '+') s++;
			else if (*s == '-') neg=1, s++;
			if (!isdigit(*s)) return 0;
			for (*dest=i=0; i<w && isdigit(*s); i++)
				*dest = *dest * 10 + *s++ - '0';
			if (neg) *dest = -*dest;
			*dest -= adj;
			goto update;
		symbolic_range:
			for (i=2*range-1; i>=0; i--) {
				ex = nl_langinfo(min+i);
				len = strlen(ex);
				if (strncasecmp(s, ex, len)) continue;
				s += len;
				*dest = i % range;
				break;
			}
			if (i<0) return 0;
			goto update;
		update:
			//FIXME
			;
		}
	}
	if (want_century) {
		tm->tm_year = relyear;
		if (want_century & 2) tm->tm_year += century * 100 - 1900;
		else if (tm->tm_year <= 68) tm->tm_year += 100;
	}
	return (char *)s;
}

@alejandro-colomar
Copy link
Collaborator

  case 'Z':
  	if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) {
  		tm->tm_isdst = 0;
  		s += len;
  	} else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) {
  		tm->tm_isdst = 1;
  		s += len;
  	} else {
  		/* FIXME: is this supposed to be an error? */
  		while ((*s|32)-'a' <= 'z'-'a') s++;
  	}
  	break;

Sorry, my bad. Actually, musl has a bug. It doesn't support %Z correctly.

Cc: @richfelker

@ikerexxe ikerexxe marked this pull request as ready for review April 7, 2025 09:55
@ikerexxe ikerexxe force-pushed the test-expiration-date branch from 3badae8 to 926fc1a Compare April 9, 2025 07:29
@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Apr 9, 2025

@alejandro-colomar your latest updates have partially fixed the problem with dates in ISO 8601 format. Right now in Alpine (with musl) dates that are not correct, for example 2025-18-18 or tomorrow, do not return an error when they should.

@alejandro-colomar
Copy link
Collaborator

@alejandro-colomar your latest updates have partially fixed the problem with dates in ISO 8601 format. Right now in Alpine (with musl) dates that are not correct, for example 2025-18-18 or tomorrow, do not return an error when they should.

How can I reproduce that in Alpine? I'm getting an error even for valid dates.

/ # cat strptime.c 
#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>

int
main(void)
{
	struct tm   tm;
	const char  *p;

	p = strptime("2025-01-18", "%F", &tm);
	if (p == NULL)
		perror("A");
	else if (*p != 0)
		perror("B");

	return 0;
}

/ # gcc -Wall -Wextra strptime.c 
/ # ./a.out 
A: No error information
/ # cat /etc/os-release 
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.21.3
PRETTY_NAME="Alpine Linux v3.21"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

@alejandro-colomar
Copy link
Collaborator

@alejandro-colomar your latest updates have partially fixed the problem with dates in ISO 8601 format. Right now in Alpine (with musl) dates that are not correct, for example 2025-18-18 or tomorrow, do not return an error when they should.

How can I reproduce that in Alpine? I'm getting an error even for valid dates.

/ # cat strptime.c 
#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>

int
main(void)
{
	struct tm   tm;
	const char  *p;

	p = strptime("2025-01-18", "%F", &tm);
	if (p == NULL)
		perror("A");
	else if (*p != 0)
		perror("B");

	return 0;
}

/ # gcc -Wall -Wextra strptime.c 
/ # ./a.out 
A: No error information
/ # cat /etc/os-release 
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.21.3
PRETTY_NAME="Alpine Linux v3.21"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

Hmmm, I've tried replacing "%F" by "%Y-%m-%d" and it works. Okay. :|

@alejandro-colomar
Copy link
Collaborator

So, now that I can work with strptime(3) in Alpine, I've tried this:

/ # cat strptime.c 
#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>

int
main(void)
{
	struct tm   tm;
	const char  *p;

	p = strptime("2025-01-18", "%Y-%m-%d", &tm);
	if (p == NULL)
		perror("1A");
	else if (*p != 0)
		perror("1B");

	p = strptime("2025-11-18", "%Y-%m-%d", &tm);
	if (p == NULL)
		perror("2A");
	else if (*p != 0)
		perror("2B");

	p = strptime("2025-18-18", "%Y-%m-%d", &tm);
	if (p == NULL)
		perror("3A");
	else if (*p != 0)
		perror("3B");

	return 0;
}

/ # gcc -Wall -Wextra strptime.c 
/ # ./a.out 
3A: No error information

It seems invalid dates are correctly reported, aren't they? It seems consistent with glibc. @ikerexxe can you reproduce the invalid date bug you're reporting with a simple program that can be run in a docker container?

@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Apr 9, 2025

Hmmm, I've tried replacing "%F" by "%Y-%m-%d" and it works. Okay. :|

I have also replaced "%F" by "%Y-%m-%d" and now it works correctly.

@alejandro-colomar
Copy link
Collaborator

Hmmm, I've tried replacing "%F" by "%Y-%m-%d" and it works. Okay. :|

I have also replaced "%F" by "%Y-%m-%d" and now it works correctly.

Thanks! I've fixed that in my PR. Please check now.

@ikerexxe ikerexxe force-pushed the test-expiration-date branch from 926fc1a to 421db6e Compare April 9, 2025 15:41
@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Apr 9, 2025

Good! That solved all issues and now CI is green

@ikerexxe
Copy link
Collaborator Author

BTW, @ikerexxe , how do you feel about these tests? Are they comprehensive about my changes? Do you feel my changes are safe with this?

Yes, I'm very happy with those changes and the tests. It seems like everything works correctly and we'll not face any regression, which was my greatest fear.

I'm unable to review this; let's see if @hallyn can.

Np, I'll ask a QE colleague to review them.

@danlavu do you mind reviewing this PR? It's based on top of #1217, so you just need to review my changes. In addition, Dominika is updating the documentation at #1243. You can use that as a guide to understand the test cases I'm implementing, and whether I'm missing some scenario. If there is something that does not fit, either in the tests or in the documentation, just tell us and we will take a look at it.

@ikerexxe ikerexxe force-pushed the test-expiration-date branch from b33d07e to 278824e Compare May 22, 2025 09:54
@alejandro-colomar
Copy link
Collaborator

@ikerexxe

Once @danlavu reviews your tests, I propose the following:

  • Drop my patches from this PR, so that only your tests remain.
  • Once your tests are alone, they should still pass CI, which means that they verify that the old behavior is the same as the new one.
  • Then, we should merge this PR with only your tests.
  • Then, we can merge my code changes.

Does that sound good?

@ikerexxe
Copy link
Collaborator Author

Yeah, that makes perfect sense.

Copy link

@danlavu danlavu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have optional nitpicks. This is because I'm unfamiliar with shadow utilities. These suggestions would have helped me understand the tests faster. Anytime I paused looking at the code, I made a comment. I'm digging deep to find any comments. Everything looks great.

@ikerexxe
Copy link
Collaborator Author

By the way, @danlavu what do you think about the test themselves? Do you think we are checking all possibilities regarding the input/output values?

@danlavu
Copy link

danlavu commented May 29, 2025

@ikerexxe, the tests are good. Though I never like negative test cases, the invalid_values cases are a waste to me. Jakub and I have always gone back and forth on this. If it is low-cost to have them, I'm okay with it.

I would remove the parametrized values of today and tomorrow, not a likely scenario.

@alejandro-colomar
Copy link
Collaborator

@ikerexxe, the tests are good. Though I never like negative test cases, the invalid_values cases are a waste to me. Jakub and I have always gone back and forth on this. If it is low-cost to have them, I'm okay with it.

I prefer keeping them.

I would remove the parametrized values of today and tomorrow, not a likely scenario.

And since today and tomorrow were valid dates until very recently, let's also keep them.

@ikerexxe
Copy link
Collaborator Author

@ikerexxe, the tests are good. Though I never like negative test cases, the invalid_values cases are a waste to me. Jakub and I have always gone back and forth on this. If it is low-cost to have them, I'm okay with it.

I'm not a great fan either, but taking the code history into account they make sense for these scenarios.

I would remove the parametrized values of today and tomorrow, not a likely scenario.

And since today and tomorrow were valid dates until very recently, let's also keep them.

This is part of the history I mention, another one is that we are moving from yacc code to C code and we don't have the expertise to fully understand what the yacc code did 100%. It's a bit complex, so I prefer to be cautious and add extra test scenarios.

@ikerexxe ikerexxe force-pushed the test-expiration-date branch from 278824e to 097381c Compare May 29, 2025 14:52
Copy link
Collaborator

@alejandro-colomar alejandro-colomar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if @hallyn wants to review or comment anything. I'm fine with merging the tests already.

Disclaimer: I can't read python, so I haven't reviewed much, other than having a quick look at it.

I approve the nomenclature of the functions, which is the only thing I feel qualified to review. :)

From @danlavu 's comments, it seems the tests are okay, so I'll approve so that you can merge if you want.

Please remember to remove my commits before merging.

@ikerexxe ikerexxe force-pushed the test-expiration-date branch from 097381c to bb8d162 Compare May 29, 2025 15:03
@ikerexxe
Copy link
Collaborator Author

Thank you! I've removed your changes and I'll let CI run. Once this is done I'll proceed to merge.

This is my last message until next week, then we can proceed to review and merge #1217

@ikerexxe
Copy link
Collaborator Author

Ok, some of the invalid dates aren't recognized as such without Alejandro's changes. I don't want to merge and leave CI broken for days, so I'll wait until Monday before proceeding.

@alejandro-colomar will you be available on Monday to work on the pending PR? This way CI won't be broken for a long time.

@alejandro-colomar
Copy link
Collaborator

Ok, some of the invalid dates aren't recognized as such without Alejandro's changes. I don't want to merge and leave CI broken for days, so I'll wait until Monday before proceeding.

@alejandro-colomar will you be available on Monday to work on the pending PR? This way CI won't be broken for a long time.

Yeah, I think mine is ready, so as soon as you or Serge approve it, we can merge it; there's not much work we need to do there. But yeah, I'll be available on Monday (until 16:00 UTC more or less, and then again available in the night).

@alejandro-colomar
Copy link
Collaborator

Ok, some of the invalid dates aren't recognized as such without Alejandro's changes. I don't want to merge and leave CI broken for days, so I'll wait until Monday before proceeding.

@alejandro-colomar will you be available on Monday to work on the pending PR? This way CI won't be broken for a long time.

Could you please mention which tests don't pass, and why? It would be good to be explicit about what is changing with my code.

@danlavu
Copy link

danlavu commented May 30, 2025

@alejandro-colomar the tests are good, all my comments are because I'm missing context. Doc strings accurately describe what the code is doing, code is easy to comprehend and will be easy to maintain and troubleshoot. With the discussion, the scenarios make more sense now.

@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Jun 2, 2025

Failed test cases are related to invalid dates that test dates outside the limits:

  • 2025-18-18
  • 2025-13-01
  • 2025-01-32

IMO, the fortifications added at #1217 improve the code.

ikerexxe added 5 commits June 2, 2025 10:00
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Dan Lavu <dlavu@redhat.com>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Dan Lavu <dlavu@redhat.com>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Dan Lavu <dlavu@redhat.com>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Dan Lavu <dlavu@redhat.com>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Dan Lavu <dlavu@redhat.com>
@ikerexxe ikerexxe force-pushed the test-expiration-date branch from bb8d162 to ae36438 Compare June 2, 2025 08:00
@ikerexxe
Copy link
Collaborator Author

ikerexxe commented Jun 2, 2025

Since everyone agrees and the CI is green I will proceed to merge this PR

@ikerexxe ikerexxe merged commit 3f03820 into shadow-maint:master Jun 2, 2025
10 checks passed
@ikerexxe ikerexxe deleted the test-expiration-date branch June 2, 2025 08:17
@alejandro-colomar
Copy link
Collaborator

Failed test cases are related to invalid dates that test dates outside the limits:

* 2025-18-18

* 2025-13-01

* 2025-01-32

IMO, the fortifications added at #1217 improve the code.

Ahhh, that makes sense. It's because the yacc(1) code was passing the dates to mktime(3), which accepts that kind of thing, unlike strptime(3).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants