# TestplanGuardian

Desktop application with a graphical interface to verify that **test
equipment logs** match a **reference log (Golden Log)**. Designed for
Test Engineers in manufacturing environments.

> **Automatiza el esfuerzo. Disfruta el crecimiento.**

---

## Table of Contents

1. [What does this application do?](#what-does-this-application-do)
2. [Package contents](#package-contents)
3. [System requirements](#system-requirements)
4. [Installation](#installation)
5. [First launch and authentication](#first-launch-and-authentication)
6. [Main interface — visual guide](#main-interface--visual-guide)
7. [Step-by-step usage](#step-by-step-usage)
8. [The Save button: what it generates](#the-save-button-what-it-generates)
9. [How to use `LogGuardian.exe`](#how-to-use-logguardianexe)
10. [Settings (gear icon ⚙)](#settings-gear-icon-)
11. [Changing the password](#changing-the-password)
12. [Recovery if you forgot the password](#recovery-if-you-forgot-the-password)
13. [Files and locations](#files-and-locations)
14. [Security and data handling](#security-and-data-handling)
15. [Do I still need Python after setup?](#do-i-still-need-python-after-setup)
16. [Troubleshooting](#troubleshooting)
17. [Appendix A — Installing Python manually](#appendix-a--installing-python-manually)
18. [Appendix B — Installing PyInstaller manually](#appendix-b--installing-pyinstaller-manually)

---

## What does this application do?

TestplanGuardian compares two HP3070-style test log files and determines
whether the manufacturing equipment is using the **correct, unaltered
testplan**.

The comparison covers two dimensions:

- **Blocks `{@BLOCK|…|`** — verifies that both logs contain exactly the
  same set of blocks (no missing or extra blocks).
- **Limits `{@LIM…|…}}`** — verifies that each block has identical limit
  values in both logs.

If both match 100%, the result is **True**. Any difference → **False**.

The application also generates a **standalone executable
(`LogGuardian.exe`)** that the equipment can run automatically as many
times as needed, **without opening TestplanGuardian again**.

---

## Package contents

| File / folder | Purpose |
|---|---|
| `TestplanGuardian.exe` | Main application (configurator). For the engineer only. |
| `setup.bat` | Automatic installation script (installs Python and PyInstaller in one click). |
| `installers/python-3.12.7-amd64.exe` | Official Python installer (for PCs without internet). |
| `installers/wheels/` | PyInstaller and dependency wheels (offline install). |
| `README.md` | This document. |

After the first **Save**, two files are generated next to `TestplanGuardian.exe`:

| Generated file | Purpose |
|---|---|
| `LogGuardian.exe` | Standalone executable that performs the comparison. |
| `LogGuardian.file` | Result of the latest comparison (`True` or `False`). |

---

## System requirements

| Component | Minimum version | Why is it needed? |
|---|---|---|
| **Windows** | 10 or later (64-bit) | Target operating system. |
| **Python** | 3.10+ | Needed **only** for the **Save** button to compile `LogGuardian.exe`. |
| **PyInstaller** | 6.0+ | Same reason: to compile `LogGuardian.exe`. |

> **Important:** If you only need to **run** an already-generated
> `LogGuardian.exe`, you do NOT need Python or PyInstaller on that
> machine. These requirements apply **only to the PC where
> `TestplanGuardian.exe` is used and the `Save` button is pressed**.

---

## Installation

### Option A — Automatic install (recommended)

1. **Copy the whole package folder** anywhere on your PC (for example,
   the Desktop or `C:\TestplanGuardian\`).
2. **Double-click `setup.bat`**.
   - Detects if Python is already installed; if not, installs it from
     the bundled installer (silent mode, no administrator required).
   - Detects if PyInstaller is already installed; if not, installs it
     from PyPI (online) or from the bundled wheels (offline).
   - Finishes with "SETUP COMPLETE".
3. **Double-click `TestplanGuardian.exe`** to open the application.

> `setup.bat` is **idempotent**: you can run it as many times as you
> like with no side effects. If everything is already installed, it
> confirms and exits.

### Option B — Manual install

If you prefer to install Python and PyInstaller by hand:

1. Follow [Appendix A](#appendix-a--installing-python-manually) for Python.
2. Follow [Appendix B](#appendix-b--installing-pyinstaller-manually) for PyInstaller.
3. Verify with:
   ```
   python --version
   pyinstaller --version
   ```
4. Double-click `TestplanGuardian.exe`.

---

## First launch and authentication

On startup, the application asks for a password:

- **Default password:** `TestplanGuardian2026`
- The input is masked (characters appear as `*`).
- You get **5 attempts** before lockout.

> Change this password right after your first successful login (see
> [Changing the password](#changing-the-password)).

---

## Main interface — visual guide

```
┌────────────────────────────────────────────┐
│                                          ⚙ │   ← gear icon (Settings)
│                                            │
│              [NEST LOGO]                   │   ← corporate logo
│                                            │
│             TestplanGuardian               │   ← title
│            Welcome, Engineer               │   ← personalizable greeting
│                                            │
│       [ 1. Upload Golden Log ]             │   ← primary button #1
│         No file loaded                     │   ← Golden Log status
│                                            │
│       [ 2. Select Target Folder ]          │   ← primary button #2
│         No folder selected                 │   ← folder status
│                                            │
│              [   Save   ]                  │   ← confirm button
│                                            │
│           Status: ready                    │   ← status line
│                                            │
│  Automatiza el esfuerzo.                   │
│  Disfruta el crecimiento.                  │
└────────────────────────────────────────────┘
```

### Elements

| Element | Description |
|---|---|
| **NEST Logo** | Corporate logo at the top of the window. |
| **Title** | "TestplanGuardian". |
| **Greeting** | "Welcome, Engineer" by default. Once you set your name in Settings, it auto-changes to "Welcome, *Your Name*". |
| **⚙ (gear)** | Top-right corner. Opens the **Settings** window (set name, change password). |
| **Button 1 — Upload Golden Log** | Picks the reference log file (the "golden master"). |
| **Button 2 — Select Target Folder** | Picks the folder containing the equipment log to be verified. |
| **Save button** | Runs the comparison and produces `LogGuardian.file` + `LogGuardian.exe`. |
| **Status line** | Shows the outcome of the last action. |
| **Footer** | Brand motto. |

---

## Step-by-step usage

1. **Open** `TestplanGuardian.exe`.
2. **Enter the password** (default `TestplanGuardian2026` on first launch).
3. **Click `1. Upload Golden Log`** and select the reference log file.
   The file name appears below the button.
   > **Note:** The Golden Log content stays **only in RAM** during the
   > session. It is never written to disk as a separate file.
4. **Click `2. Select Target Folder`** and choose the folder containing
   the log of the equipment under test. The path appears below the button.
   > **Important:** The folder should contain a single log file (if it
   > has multiple files, only the first one is used).
5. **Click `Save`**.
   - The app checks that Python and PyInstaller are installed.
   - Compares the two logs and writes the result to `LogGuardian.file`.
   - Compiles `LogGuardian.exe` (30–60 seconds, with a progress bar).
   - Shows a summary when done.

---

## The Save button: what it generates

When you press **Save** with a Golden Log loaded and a valid target
folder, **two files** are produced next to `TestplanGuardian.exe`:

### 1. `LogGuardian.file`

Plain text file containing one word:

- `True` → blocks and limits match 100%.
- `False` → at least one difference exists.

It is **overwritten** on every Save.

### 2. `LogGuardian.exe`

Standalone executable (~8–10 MB) that:

- Embeds the **parsed reference data** from the Golden Log (block list +
  limit map). It does **not** contain the original Golden Log file —
  only the data needed for the comparison.
- Embeds the target folder path.
- When executed, opens the first file in that folder, compares it, and
  writes `True`/`False` to `LogGuardian.file`.
- **Asks for no password, shows no window, opens no console.** Fully silent.

It is **overwritten** on every Save.

---

## How to use `LogGuardian.exe`

Once generated, `LogGuardian.exe` can be invoked:

- **Manually:** double-click the file.
- **Programmatically** from another script, MES, or test sequence.
- **From the command line:**
  ```
  LogGuardian.exe
  ```
- **From a Windows Scheduled Task.**

After it runs, just read `LogGuardian.file` to know the result. For
example, from a `.bat`:

```bat
@echo off
LogGuardian.exe
set /p RESULT=<LogGuardian.file
echo Result: %RESULT%
```

---

## Settings (gear icon ⚙)

The `⚙` icon in the top-right corner opens the **Settings** window:

| Field | Purpose |
|---|---|
| **Engineer name** | Name shown in the greeting ("Welcome, *name*"). Leave empty to show "Welcome, Engineer". |
| **Change Password...** | Opens a sub-dialog to change the access password. |
| **Save** | Persists changes. |
| **Cancel** | Closes without saving. |

Changes persist across sessions (see [Files and locations](#files-and-locations)).

---

## Changing the password

1. Open `⚙` (gear).
2. Click **`Change Password...`**.
3. Fill in the three fields:
   - **Current password:** your current password.
   - **New password:** the new one (minimum 6 characters).
   - **Confirm new:** repeat it.
4. Click **OK**. If everything checks out, you'll see "Password updated".

> If you mistype the current password, or the new ones don't match,
> you'll get a clear error message and the change is not applied.

---

## Recovery if you forgot the password

If you fail **5 consecutive attempts**:

1. The input locks and a message appears:
   > *Locked. Press Ctrl+Shift+R for recovery.*
2. Press **`Ctrl + Shift + R`**.
3. The input re-enables in **recovery mode**:
   > *Recovery mode: enter the default password.*
4. Type the default password: **`TestplanGuardian2026`**.
5. If correct, you enter the application **and the stored password is
   automatically reset to the default**, so you can log in normally next
   time.

> Only **one attempt** is allowed in recovery mode. If you fail, the app
> closes and you must reopen it.

---

## Files and locations

| File | Location | Notes |
|---|---|---|
| `TestplanGuardian.exe` | Wherever you copied it | Can be moved freely. |
| `LogGuardian.exe` | Same folder as `TestplanGuardian.exe` | Overwritten on every Save. |
| `LogGuardian.file` | Same folder as `TestplanGuardian.exe` | Overwritten on every Save and on every run of `LogGuardian.exe`. |
| `config.json` | `%APPDATA%\TestplanGuardian\` | Stores engineer name and password hash. **Per Windows user.** |

> The `config.json` file **is hidden from the executable folder** — it
> lives in the user's app-data folder to keep the deployment path clean.
> To open it quickly: paste `%APPDATA%\TestplanGuardian` into the
> Windows Explorer address bar.

---

## Security and data handling

| Aspect | Implementation |
|---|---|
| **Golden Log** | Loaded into RAM via `open().read()` and kept only in a session variable. **Never written to disk** as a separate file. |
| **Data embedded in `LogGuardian.exe`** | Only the **parsed** data (block list + limit map). Not the raw Golden Log content. |
| **Password** | Stored as a **SHA-256 hash** in `config.json`. Never in plaintext. |
| **Recovery mode** | Requires knowing the default password, and resets the stored hash to the default after one use. |
| **Lockout** | 5 failed attempts → lockout with recovery option. |

---

## Do I still need Python after setup?

Short answer: **it depends on which machine and what you want to do**.

| Machine | Needs Python + PyInstaller? |
|---|---|
| The one **running** `TestplanGuardian.exe` *just to open the app and look around* | **No** — the Python interpreter is bundled inside the .exe. |
| The one **running** `TestplanGuardian.exe` and **pressing Save** | **Yes** — Save compiles `LogGuardian.exe` using the system PyInstaller. |
| The one **running** `LogGuardian.exe` (the test equipment PC) | **No, never.** It's a fully self-contained binary. |

So:

- If, after configuring once, you move `LogGuardian.exe` to another PC
  to run it there: **that PC does not need Python.**
- If you'll keep using `TestplanGuardian.exe` to **regenerate** the
  configuration (new Golden Log, new target folder): **you do need
  Python and PyInstaller on that PC.**
- If you're done configuring and won't touch TestplanGuardian again,
  you could technically uninstall Python and `LogGuardian.exe` would
  keep working. If you ever need to reconfigure, just run `setup.bat`
  again.

---

## Troubleshooting

### "Python is not installed on this machine"
Appears when you press Save. Means Python is not on the system PATH.
Run `setup.bat` again, or see
[Appendix A](#appendix-a--installing-python-manually).

### "PyInstaller is not installed"
Appears when you press Save. Python is there, but PyInstaller is missing.
Run `setup.bat` again, or see
[Appendix B](#appendix-b--installing-pyinstaller-manually).

### "No log file found in: …"
The target folder you selected is empty. Place the equipment log inside
it and try again.

### The Save button seems unresponsive for several seconds
That's normal — PyInstaller takes 30–60 seconds to compile
`LogGuardian.exe`. A progress dialog appears while this is happening.

### "Locked. Press Ctrl+Shift+R for recovery."
You failed the password 5 times. Follow the steps in
[Recovery if you forgot the password](#recovery-if-you-forgot-the-password).

### `LogGuardian.exe` always writes `False`
- Make sure the file in the target folder is actually the test log (not
  a config file or other artifact).
- If the target folder moved to a different path after `LogGuardian.exe`
  was generated, run Save again in `TestplanGuardian.exe` to regenerate
  the executable with the new path.

### Windows SmartScreen warns about the .exe
Because the executable is not digitally signed, Windows shows a warning
the first time. Click **More info → Run anyway**.

---

## Appendix A — Installing Python manually

### Online (recommended)

1. Download the installer from:
   https://www.python.org/downloads/windows/
2. Run the `.exe`.
3. **VERY IMPORTANT:** check the *"Add python.exe to PATH"* box on the
   first installer screen.
4. Click **Install Now**.
5. Verify by opening `cmd` and running `python --version`.

### Offline / no internet

If the target machine has no internet:

1. From another machine with internet, download the installer `.exe`
   (~28 MB) from python.org.
2. Copy it via USB or network to the target machine.
3. Run it the same way as the online case.

> The package you received already ships with this installer at
> `installers/python-3.12.7-amd64.exe`.

---

## Appendix B — Installing PyInstaller manually

### Online (recommended)

Once Python is installed:

```
pip install pyinstaller
```

Verify with:

```
pyinstaller --version
```

### Offline / no internet (how the bundled wheels work)

A wheel (`.whl`) is the standard Python package format — basically a
ZIP file with pre-built code, ready to install without compilation.

The trick to install offline is to download the package **and all its
transitive dependencies** as wheels first:

1. **From a machine WITH internet:**
   ```
   pip download pyinstaller -d wheels
   ```
   This populates the `wheels/` folder with PyInstaller + every
   dependency (altgraph, pefile, pyinstaller-hooks-contrib,
   pywin32-ctypes, packaging, setuptools).

2. **Copy the `wheels/` folder** to the offline machine (USB, network,
   etc.).

3. **On the offline machine:**
   ```
   pip install --no-index --find-links wheels pyinstaller
   ```
   - `--no-index` → don't reach out to PyPI.
   - `--find-links wheels` → resolve everything from this local folder.
   - `pyinstaller` → the package name; pip walks the dependency tree
     using the local wheels.

> The package you received already ships with these wheels at
> `installers/wheels/`. The `setup.bat` script uses them automatically
> when there is no internet.

---

## Support

If you hit a problem not covered here, please note:

- What you were doing.
- The exact message that appeared (a screenshot helps).
- Your Windows version.
- The output of `python --version` and `pyinstaller --version`.

Then report the incident to the Test Engineering team.
