Stage #MG5 (Java): the tests are failing but if I re-execute the command it works

I’m not stuck on Stage #MG5, but I witness behavior.

What I see is that one time out of two, the tests fail but if I re-execute the test then it succeeds (without changing my code). My guess is that it is linked with something happening at the [setup] phase. As one can see in the following logs, there are two [setup] logs, so my understanding is that the PATH env variable is modified twice but is it persisted?

Here are my logs:

tester::#MG5] Running tests for Stage #MG5 (The type builtin: executable files)
[tester::#MG5] [setup] export PATH=/tmp/qux:$PATH
[tester::#MG5] [setup] export PATH=/tmp/bar:$PATH
[tester::#MG5] [setup] Available executables:
[tester::#MG5] [setup] - my_exe
[tester::#MG5] Running ./your_program.sh
[your-program] $ type cat
[your-program] cat is /bin/cat
[tester::#MG5] ✓ Received expected response
[your-program] $ type cp
[your-program] cp is /bin/cp
[tester::#MG5] ✓ Received expected response
[your-program] $ type mkdir
[your-program] mkdir is /bin/mkdir
[tester::#MG5] ✓ Received expected response
[your-program] $ type my_exe
[your-program] my_exe is /tmp/qux/my_exe
[tester::#MG5] Output does not match expected value.
[tester::#MG5] Expected: "my_exe is /tmp/bar/my_exe"
[tester::#MG5] Received: "my_exe is /tmp/qux/my_exe"
[your-program] $ 
[tester::#MG5] Assertion failed.

Now, if I re-execute the command, I see:

[tester::#MG5] Running tests for Stage #MG5 (The type builtin: executable files)
[tester::#MG5] [setup] export PATH=/tmp/baz:$PATH
[tester::#MG5] [setup] export PATH=/tmp/baz:$PATH
[tester::#MG5] [setup] Available executables:
[tester::#MG5] [setup] - my_exe
[tester::#MG5] Running ./your_program.sh
[your-program] $ type cat
[your-program] cat is /bin/cat
[tester::#MG5] ✓ Received expected response
[your-program] $ type cp
[your-program] cp is /bin/cp
[tester::#MG5] ✓ Received expected response
[your-program] $ type mkdir
[your-program] mkdir is /bin/mkdir
[tester::#MG5] ✓ Received expected response
[your-program] $ type my_exe
[your-program] my_exe is /tmp/baz/my_exe
[tester::#MG5] ✓ Received expected response
[your-program] $ type invalid_mango_command
[your-program] invalid_mango_command: not found
[tester::#MG5] ✓ Received expected response
[your-program] $ type invalid_blueberry_command
[your-program] invalid_blueberry_command: not found
[tester::#MG5] ✓ Received expected response
[your-program] $ 
[tester::#MG5] Test passed.

As one can see, the PATH is set twice using the same input in my second snippet, hence the test succeeds. I don’t know if this is a bug or if it is because of my code though. I would appreciate it if someone could tell me, please :).

And here’s a snippet of my code:


       // Builtins is a class that act as a Set
        Builtins builtins = new Builtins();
        builtins.add("echo");
        builtins.add("exit");
        builtins.add("type");
        builtins.add("pwd");
        builtins.add("cd");

 // ...
                case "type":
                    if (builtins.contains(parameters)) {
                        System.out.println(parameters + " is a shell builtin");
                    } else {
                        String filePath = this.getFilePath(parameters);
                        if (filePath == null) {
                            System.out.println(parameters + ": not found");
                        } else {
                            System.out.println(parameters + " is " + filePath);
                        }
                    }
                    break;

// ...

    private Set<String> getPaths() {
        Set<String> paths = new HashSet<>();
        for (String pathString : System.getenv("PATH").split(":")) {
            paths.add(pathString);
        }
        return paths;
    }

// ...

    private String getFilePath(String fileName) {
        // this.pathSet is initialized using this.getPaths() right above.
        for (String path : this.pathSet) {
            File file = new File(path + "/" + fileName);
            if (file.exists()) {
                return file.getPath();
            }
        }
        return null;
    }

Thanks if you can help!

I’ll take a look shortly.

Hi @Ferdinanddb, the flakiness stems from here:

It’s technically incorrect to parse the PATH only once in the constructor because PATH can be modified dynamically.

Instead, every time you run type my_exe, your implementation should re-evaluate PATH, ensuring it reflects any potential updates.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.